How to run DDL after Spring auto create db? - java

My question is simple. How to run any DDL statements after Spring's automatic schema creation?
I have set the following in my application-test.properties to auto create the database schema from the entity Java classes.
spring.jpa.hibernate.ddl-auto=create-drop
I'd like to change the data type of one column in one table after the schema is auto created.
I tried having a schema.sql file in the classpath, but that didn't help.
Any help please.

Scripts which you specify in script will run before it create database.
So when you fire Alter table command, you will get Table not found kind of error.
What I would suggest is to create database via SQL file only and set
spring.jpa.hibernate.ddl-auto=none so system wont create auto database.
Now to make your SQL file run, You can create the schema and initialize it based on the platform. Platform value is of spring.datasource.platform. Now you can create files schema-${platform}.sql and data-${platform}.sql which is processed by Spring Boot. It allows you to choose the database specific scripts if necessary. You can choose the vendor name of database(platform) like hsqldb, h2, oracle, mysql, postgresql, and so on.
I have tested with postgres and It worked for me. Sql file name was schema-postgres.sql
Set below properties in application.properties file
spring.jpa.database=POSTGRESQL
spring.datasource.platform=postgres
spring.datasource.url=jdbc:postgresql://localhost:5432/poc
spring.datasource.username=postgres
spring.datasource.password=postgres
spring.jpa.hibernate.ddl-auto=none
spring.datasource.initialization-mode=always

Related

How to execute SQL files outside of spring application using maven command?

I have a spring boot application which is using Postgresql and also maven. It uses the Flyway migration to migrate database changes. I want to have a specific SQL file and run it by a command to insert some records for configuration whenever I want.
Could you please help me to handle this?
The specific topic is detailed here Spring Database Initialization.
Basically set the initialization values as you require:
spring.datasource.platform=postgres
spring.jpa.hibernate.ddl-auto=update
spring.datasource.initialization-mode=always
....
E.g. (there are much more options) if you place into resources the file data.sql it will be executed and you can add your fixtures.
For specific Flyway migrations you should check Execute Flyway Database Migrations on Startup.
Basically you add every new migration version script and it will be checked for every deployment.

How is H2 database different compared to Postgresql? Does H2 create tables on its own when used in a microservice

I'm new to programming and I'm trying to read a json and store in a database using springboot, when i use H2 i dont have to create table structure it creates on its own but when i use postgres i get errors that unable to find table. is there anyway to create tables automatically in postgres ?
How do they work and postgres is not able create tables on its own, Am i doing anything wrong?`
spring.datasource.url=jdbc:h2:mem:testdb
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
spring.h2.console.enabled=true
spring.datasource.initialization-mode=always
spring.datasource.platform=postgres
spring.datasource.url=jdbc:postgresql://localhost:5432/MyDB
spring.datasource.username=postgres
spring.datasource.password=1234
spring.jpa.show-sql=false
spring.jpa.properties.hibernate.jdbc.lob.non_contextual_creation=true
There's a property you need to set for PostgreSQL to automatically create the tables on startup:
spring.jpa.hibernate.ddl-auto=update
Or if you want to start from a clean database everytime:
spring.jpa.hibernate.ddl-auto=create
For embedded databases like H2, Spring Boot will set spring.jpa.hibernate.ddl-auto=create automatically
See also this 12-year old question about why you should not do that in production:
Hibernate: hbm2ddl.auto=update in production?
In production, you should manage the database tables outside of your application, or use something like Liquibase or Flyway
If the database is embedded the default value of spring.jpa.hibernate.ddl-auto is create-drop. If not, default value is none.
Check this out - https://docs.spring.io/spring-boot/docs/1.1.0.M1/reference/html/howto-database-initialization.html

Cannot populate database with liquibase

I'm building a small spring-boot application. I'm using spring-data-jpa to create the database schema and liquibase to populate it with test data.
application.properties:
spring.datasource.url=jdbc:postgresql://localhost:5432/book-db
spring.datasource.driver-class-name=org.postgresql.Driver
spring.datasource.username=admin
spring.datasource.password=lTIDDYz3n3jD3BeYaAJz
spring.jpa.generate-ddl=true
spring.jpa.hibernate.ddl-auto=create
spring.jpa.properties.hibernate.jdbc.lob.non_contextual_creation=true
According to the documentation no configuration for liquibase is required if I have a gradle dependency and master changeLog under the default path.
db.changelog-master.yaml:
databaseChangeLog:
- changeSet:
id: 1
author: jb
changes:
- sqlFile:
path: db/migration/insert-books.sql
insert-books.sql:
--liquibase formatted sql
--changeset admin:1
delete from book;
insert into book (id, title)
values (nextval('seq'), 'Functional Programming for Mortals');
commit;
I have tried it with and without commit. The tables databasechangelog and databasechangelog are created successfully and contain the migration (insert-books).
The migration goes through, because if I add an invalid insert (to some table that does not exist), I get the exception:
ERROR: relation "xxx" does not exist
How to populate the database with data in insert-books.sql script using liquibase?
Don't use both, liquibase and JPA, to manage the DB structure. If you want to use liquibase, set JPA (Hibernate) to just validate the schema and manage the schema within liquibase.
spring.jpa.hibernate.ddl-auto=validate
The problem with your solution is in the order of operations. When your application starts, it first runs liquibase, which inserts the data, then JPA is started and the schema is created from scratch.
Try dropping the schema before running the app, I bet the migration (liquibase) will fail.
Liquibase has to be in charge of the schema, there is a way to add liquibase to an existing database, but it again makes liquibase the owner of the schema:
Using liquibase on the existing database

Springboot default data.sql not loading on startup

I've got this springboot application that is working with a postgresql database. My application-dev.properties file is as follows:
spring.datasource.platform=postgres
spring.datasource.url=jdbc:postgresql://localhost:5432/postgres
spring.datasource.username=postgres
spring.datasource.password=root
spring.datasource.data=classpath:/sql/dev-data.sql
spring.jpa.properties.hibernate.default_schema=myschema
spring.jpa.show-sql=true
spring.jpa.database=POSTGRESQL
The database is installed in my development machine, and already initialized. dev-data.sql is in src/main/resources/sql and right now only deletes everything on a specific table (lets call it myschema.example_table) and inserts some registries. (This is intended to check the functionality works than for an actual use):
delete from myschema.example_table where id > 0;
insert into myschema.example_table (id, val1, val2) values (1, "Hello", "Petecander");
insert into myschema.example_table (id, val1, val2) values (2, "Goodbye", "Gromenauer");
My issue is that... nothing happens. Is as if there wasn't anything related to the dev-data.sql file at all. So, I'm completely at a loss here. I've been browsing for a while, and reading about a lot of different switches that can be enabled on the application.properties file, but nothing. Any idea?
EDIT: Just to provide a bit more of info that I've been asked down there: The application loads fine and can perform some basic CRUD stuff against the database (Just read stuff at the moment), so the application-dev.properties file seens that is being loaded right.
Hibernate will only execute data.sql for create or create-drop
Add the following property to your application properties
spring.jpa.hibernate.ddl-auto=create or spring.jpa.hibernate.ddl-auto=create-drop
This is required along with the property
spring.datasource.initialization-mode=always for external (not embedded) databases.
Did you try to name file data.sql? I think it could help https://www.baeldung.com/spring-boot-data-sql-and-schema-sql
Looks like some of the suggestions are deprecated now.
spring.datasource.initialization-mode=always
Needs to be replaced with:
spring.sql.init.mode=always
Here is a picture of my application.properties settings for a local H2 database if this helps anybody:
Spring H2 Settings
I've faced a similar issue and found my answer here. If you add:
spring.datasource.initialization-mode=always
To your properties it should work.
For embedded database like h2 , adding below entries in application.properties worked for me.
spring.datasource.data=classpath:mysql.sql
For spring boot version 2.7, adding spring.sql.init.mode=always to application properties will work.

How to get ddl auto generated script in Spring boot JPA/Hibernate?

Is there a way to quickly get initial SQL script for the database that is being generated by hibernating through ddl-auto property?
I would like to get an initial SQL script for the flyway as a quick start.
use property spring.jpa.show-sql = true and it will print all script on console in format.
use ddl-auto as you did and take backup of schema for your respective DB and use that as initial script
example - mysql , postgres
You can see the DDL script generated by Hibernate in a Spring boot application by setting the logging level of Hibernate to debug mode in the application.properties file of your project.
logging.level.org.hibernate.SQL=DEBUG

Categories

Resources