How to create DataJpaTest with Flyway migrations that use Postgres code? - spring

I had have some difficulties to run my tests in spring boot app that have flyway to manage migrations, all tests up the applications and fail because the flyway try to run migrations.
I have installed H2 and use #DataJpaTest do try fix that, the application start normally but crash because the code that exists on the migration's file. Example:
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
CREATE TABLE app_user (
id uuid DEFAULT uuid_generate_v4() NOT NULL PRIMARY KEY,
name varchar(200) NOT NULL
);
As you can see all migrations file have postgres syntax, and the properties are hibernate: ddl-auto: validate
So have some way to only in tests create a H2 table from the #Entity without use migrations or all tests run without start spring application? If true can I test repositories without spring application?
Thanks

I would recommend to disable Flyway and enable Hibernate auto schema creation in the tests.
You can use properties to enable and disable features:
disable Flyway: spring.flyway.enabled=false
enable Hibernate Schema creation spring.jpa.hibernate.ddl-auto=create
For example
#SpringBootTest(properties = {
"spring.flyway.enabled=false",
"spring.jpa.hibernate.ddl-auto=create" })

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.

Automatically baselining a database with Flyway in a Spring Boot project

I'm trying to add Flyway to a Spring Boot project. In accordance with the instructions, I've created my initial DDL script and committed it to src/main/resources/db/migration/V1__base_version.sql.
If I run the baseline command, this will create the flyway_schema_history table and set the baseline version therein to 1.
While this works fine for my local database, I would like this to happen automatically on the other developers' local environments, UAT environment, etc.
I tried adding the following property to the Spring Boot config
spring:
flyway:
baseline-on-migrate: true
I expected this to do the same thing as the baseline command when the Spring Boot app starts up if the flyway_schema_history table does not exist, i.e. create this table and insert a row specifying the current schema version, but it didn't.
Is there a way to automatically baseline the database when the app starts up?

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

Import database provisioning script with JPA

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.

Javers - How to drop and create Javers tables in Spring Boot?

How to create the Javers tables such as jv_snapshot, from scratch every time the Spring Boot Application is run?
JaVers creates its tables if they not exist and never drops them. There is no create-drop option like in Hibernate. For testing we recommend using in-memory db (H2) and running each test on a new and empty db instance.
Yes, it will be auto created.
See a demo here:
https://github.com/yhjhoo/javers-demo
I had the same issue as I wanted to clear all the data from JaVers for every start of my Spring Boot application in my dev environment using postgres.
I set up in my application.properties as follow:
spring:
profiles: dev
jpa:
hibernate:
ddl-auto: create-drop
datasource:
initialization-mode: always
continue-on-error: true
Since initialization-mode is now active, Spring boot will look at the file data.sql under src/main/ressources and run the SQL inside.
TRUNCATE jv_commit CASCADE;
TRUNCATE jv_commit_property CASCADE;
TRUNCATE jv_global_id CASCADE;
TRUNCATE jv_snapshot CASCADE;
Even if the tables don't exist, Spring Boot will still start thanks to the continue-on-error setting.

Resources