Import database provisioning script with JPA - spring

I'm suing Spring Boot with JPA. I tried to create src/main/resources/import.sql script for provisioning users into application properties:
spring.datasource.jndi-name=java:/global/production
spring.datasource.driver-class-name=org.mariadb.jdbc.Driver
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MariaDBDialect
spring.jpa.show-sql = true
spring.jpa.hibernate.ddl-auto = update
spring.datasource.data=classpath:import.sql
But unfortunately when I deploy the application the script is not run. Do you know with JPA what is the proper way to create SQL provisioning script?

If you need to initialized your database (if I understand you correctly), all you need to do in your Spring Boot project is just provide file data.sql with your DML scripts in your root classpath location (i.e. in resources dir):
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.
Source.
Another approach you can find here.

With the #Sql annotation you can specify the path of the file you want to run before the tests. For example:
#TestPropertySource("classpath:application-test.properties")
#Sql("/data.sql")
class MyClassTest
You can read more in here.

Related

Springboot Database Initialization

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.

Unable to run SQL script to initialize test data for Spring Boot test

I have a Spring Boot 2.3 reactive application with webflux and r2dbc. Normally it runs on MS Sql database. I want unit tests to run on H2. I got to the point when correct database driver is loaded based on which application.properties file is in use (main or test). But I can't figure out how to run SQL scripts to create schema and load data.
Tried the following without success:
schema-XXX.sql, data-XXX.sql, they work fine with non-reactive JPA.
#Sql annotation referring to the *.sql files in resources directory.
ConnectionFactoryInitializer bean located in the same package as application configuration files, but under the test source tree. #Configuration and #Bean are used properly, but the bean is not instantiated. Maybe this is the problem?
Nothing in the log suggests that there was even a failed attempt to execute *.sql files.
Thank you.

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

How to configure Spring Boot Application to run on a specific database when launching

I have a Spring MVC Application developed with Spring Boot. This is application is just for learning purposes, by the way.
By default, the app launches and uses a MySQL database. For unit and integration testing, I use an in-memory H2 database and it works perfectly.
So for that, I have two application.properties. One is under /src/main/resources/application.properties.
spring.datasource.driver-class-name = com.mysql.jdbc.Driver
spring.datasource.url = jdbc:mysql://localhost/myDatabase
spring.datasource.username = root
spring.datasource.password = mysql
spring.thymeleaf.mode=LEGACYHTML5
spring.thymeleaf.cache=false
The other application.properties in under /src/test/resources/application.properties
spring.datasource.driver-class-name=org.h2.Driver
spring.datasource.url=jdbc:h2:mem:db;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE"
spring.datasource.username=sa
spring.datasource.password=sa
Now, I have to use Selenium for automated website testing and I don't want my MySQL database to be populated with test data.
I haven't done this previously in Spring, but I would like my application to work like this:
Launch from terminal my application with certain commands specifying what database it should use. It should launch on localhost:8080
And then, run all Selenium test in localhost:8080. All the data generated with Selenium tests is only kept in memory as long as the application is running
How to do this in a Spring Boot Application using an application.properties or other configuration?
Create a separate properties file named application-test.properties and place it under /src/test/resources. The test database properties (or any other test specific properties) should go here.
On top of your test class, use this annotation #ActiveProfiles("test").
#ActiveProfiles("test")
public class MyTest {
...
}
Spring should do this for you automatically. To run application.properties from src/test/resources when you are running tests because spring runs with "test" profile. If not, add #ActiveProfiles("test") annotation on your test class (and by that I mean the class where you have your tests, not the class under test). If even that doesn't work, you can rename your src/test/resources/application.properties to src/test/resources/application-test.properties and select your profile in your run configuration (there is a field called 'profile'). Reference and more info.

Resources