Springboot Database Initialization - spring

As I understand from Spring reference docs, we can use data.sql and schema.sql for initializing the database.
When there are multiple instances of the application running against a single database, how to make the data.sql, schema.sql run only once and instead of executing in all the containers.

You need to disable the default spring data initialization. You can do this through your properties file by
spring.datasource.initialization-mode=never
While Spring do not recommend using multiple data source initialization technologies, if you want script-based DataSource initialization to be able to build upon the schema creation performed by Hibernate, set
spring.jpa.defer-datasource-initialization
To true, this will defer data source initialization until after any EntityManagerFactory beans have been created and initialized.
And for managing your database across multiple application instance you can use Flyway and Liquibase, sing the basic schema.sql and data.sql scripts alongside Flyway or Liquibase is not recommended and support will be removed in a future release.

Related

Spring Boot h2 initial data not creating table first

I am trying to create a small Spring Boot setup with a h2 database.
Now I have a weird problem, which I can't solve.
If I don't create an data.sql for initial data, the app starts fine and creates my entity tables.
If I create an data.sql for initial data and keep the existing table from previous step, everything works fine.
If I create an data.sql for initial data and remove my existing h2 file, I get the error that it can't import the data, because the table is missing.
How do I tell Spring to create my tables before importing the initial data?
This is covered in the release notes for Spring Boot 2.5:
By default, data.sql scripts are now run before Hibernate is initialized. This aligns the behavior of basic script-based initialization with that of Flyway and Liquibase. If you want to use data.sql to populate a schema created by Hibernate, set spring.jpa.defer-datasource-initialization to true. While mixing database initialization technologies is not recommended, this will also allow you to use a schema.sql script to build upon a Hibernate-created schema before it’s populated via data.sql.

Spring Boot: Executing the Newer version of SQL file each time we rebuild the application

I have a spring-boot application with PostgreSQL. Some of the tables are created using models and other tables have to be created prior to the start of the application or while starting the application. That can be done by running an SQL file while startup.
But DB tend to change over time, we may have to alter some of the tables, add some new tables without disturbing the existing data in the tables, etc.
Is there a way to add new SQL files, and run only the SQL files which was not run in spring-boot application each time when we rebuild and rerun? And don't run any of the SQL files while start-up if everything were already executed?
For your scenario liquibase is the best solution. You can merge liquibase on your spring boot application.
Ex: https://javadeveloperzone.com/spring-boot/spring-boot-liquibase-example/
You can use flyway. It allows you to have versioned sql scripts:
flywaydb.org
flywaydb spring boot plugin
Examples:
Spring Boot Database Migrations with Flyway
Incrementally changing your db with java and flyway

How can you use h2 in memory data in a Spring Boot API?

We are building a new API using Spring-Boot. For testing, we want to use the h2 in memory data base to test our API.
How do you setup h2 db so Spring-boot can use that data during that session?
Ideal situation, I can call GET and retrieve everything that was created in my h2 db
In your test folder, create a Defaultdatasourceconfig class, that will have all the necessary beans (like DSbean, TXManager bean etc). For the new DriverManagerDataSource() method, pass the necessary datasource properties (create a properties class with the below fields and annotate them with #Value and the property names), add those properties to your application-test.properties file
db.hsql.url=jdbc:hsqldb:mem:testdb
db.hsql.username=sa
db.hsql.password=sa
db.hsql.driver.name=org.hsqldb.jdbc.JDBCDriver
spring.datasource.platform=hsqldb
If you want to load specific tables related only for your usecase, add this to the prperties files spring.datasource.schema=classpath:abc.sql and add abc.sql under the same folder as application-test.prpoerties.
So, when you run the test, when the context builds, it will use hsql db as Primary db, loads table by executing the sql and uses this db.
you will need to add hsql driver in your classpath.
Same can be done with h2

Load different schema.sql and data.sql for different datasources in spring boot

I have two datasources in my Spring Boot application. I want to initialize database at startup for local profile for both datasource with two different schema.sql and data.sql files. How to do it?
According to the section 85.3 Initialize a Database of the documentation:
Spring Boot can automatically create the schema (DDL scripts) of your DataSource and initialize it (DML scripts). It loads SQL from the standard root classpath locations: schema.sql and data.sql, respectively. In addition, Spring Boot processes the schema-${platform}.sql and data-${platform}.sql files (if present), where platform is the value of spring.datasource.platform. This allows you to switch to database-specific scripts if necessary. For example, you might choose to set it to the vendor name of the database (hsqldb, h2, oracle, mysql, postgresql, and so on).

How can I make my flyway default DB pointing to different db and my actual Spring boot Application to some other DB

I am trying to integrate flyway to my existing Spring boot app. My requirement is, the default table created by flyway needs to be created on different DB schema and my applications actual table migration must happen on different schema. Reason being, no addition table must be created on the applications DB schema. Currently we are using Mysql
We had a Spring Boot app with the flyway configuration in application.properties file for different environments:
flyway.enabled=true
flyway.url=jdbc:postgresql://localhost:5432/finance
flyway.schemas=user
flyway.password=password
flyway.user=postgres
flyway.baseline-on-migrate=true
We had the application-dev.properties, application-local.properties and application-aws.properties with the configuration specific to the environment
Flyway provides a property flyway.schemas. When the flyway.schemas property is set (multi-schema mode), the schema history table is placed in the first schema of the list.
https://flywaydb.org/documentation/commandline/migrate.html
ex:flyway.schemas=schema1,schema2,schema3

Resources