Liquibase issue while running spring boot integration test - java

I am trying to run the integration test in spring boot which creates liqubase bean and run all the changesets. I get an error while running below change set in yaml file.
spring boot integration test run exception
- changeSet:
id: 2
author: XXX
changes:
- sql:
splitStatements: true
sql: CREATE ROLE dba_user LOGIN PASSWORD 'dba_user';
stripComments: true
Exception is
Caused by: org.h2.jdbc.JdbcSQLException: Syntax error in SQL statement "CREATE ROLE DBA_USER LOGIN[*] PASSWORD 'dba_user' "; SQL statement:
CREATE ROLE dba_user LOGIN PASSWORD 'dba_user' [42000-196]
Why does it add [*] or is there some other issue? The same exception I get while running changeset to create a view.

Your test is running against H2 database, which doesn't have CREATE ROLE feature.
BTW, I don't think it is good idea to create role via Liquibase. Liquibase is meant to be used for DB schema/data migrations, not for creating DB instance (where DB role creation falls as well). I would suggest to create role when DB instance is being created (doesn't matter if it is automated or manual).

If you have SQL queries that not compatible with H2, you can use testcontainers to use PostgreSQL with your integration tests. It runs docker containers under the hood for your database needs in tests and you can query the containerized PostgreSQL.

preConditions:
- onFail: MARK_RAN
- not:
- dbms:
type: h2
I found a way to skip database specific script with this. So it won't run if it's h2.

Related

Can spring create a new schema (using flyway) at startup and then connect to it via default datasource?

My spring-boot app has following properties set,
spring.jpa.hibernate.ddl-auto=none
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/my-schema
spring.datasource.username=root
spring.datasource.password=*****
spring.flyway.check-location=false
spring.flyway.createSchemas=true
spring.flyway.schemas=my-schema
The schema 'my-schema' does not pre-exist and I would want for it to be created by flyway and then be used by spring-boot app to sping up HikarCP datasource.
If I run the application with the above configurations I get the following error upon startup:
Caused by: org.flywaydb.core.internal.exception.FlywaySqlException:
Unable to obtain connection from database: Unknown database 'my-schema'
Now, if I change,
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/
The application starts up perfectly and creates the schema. However, when it tries to query any table the thrown exception is:
java.sql.SQLException: No database selected
You can configure Flyway with a URL that's used purely for migrations and then configure your app to use a different URL. Something like this:
spring.flyway.url=jdbc:mysql://127.0.0.1:3306
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/my-schema
You'll also need to provide credentials for the Flyway-specific connection to the database using spring.flyway.user and spring.flyway.password.

H2 Database doesn’t support schema.package.function structure

In my project we are using oracle database as the main application db and H2 as in memory database to run only the integration test cases. Oracle db has many functions which are of the structure "schema.package.function()". The problem is, i'm not able to recreate the same function in H2 for integration test cases as H2 treats it in the form of "dbname.schemaname.functionname()".
for example : When code runs with oracle db , "SELECT MDM.NEXT_KEYS.NEXT_REF_SOURCE_KEY from dual" works. During integration test case on H2, it throws error "DB MDM not found". So i set the db name as MDM and schema name as NEXT_KEYS in h2 setup.It worked. But my next function PAYERS.KEY_TRANSLATIONS.CORE_ENHANCED_DESC_4_KEY fails now saying "DB PAYERS not found".
Changing the oracle functions is out of the equation as they are used by multiple teams.
If this is not possible with H2 , can you suggest a good alternate in-memory db for spring boot
Appreciate your help !
I was able to fix the issue. Adding the solution link here so that it might help someone
Setting this flag IGNORE_CATALOGS=TRUE fixed the issue. When it is enabled, name of catalog (database) is ignored.
spring.datasource.url = jdbc:h2:mem:testdb;MODE=Oracle;IGNORE_CATALOGS=TRUE
Refer the below link https://github.com/h2database/h2database/issues/2893

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

How to create table postgresql Heroku?

I have database postgresql in Heroku and i have local app. My entity is "Product".
When i wanna open my application in spring boot i get ERROR: relation "product" does not exist.
I dont have any idea how create new table "product" in postgresql.
In mysql everythink is good
You can with do it manually by running heroku pg:psql and then running the appropriate SQL statements. Or you can use a migration framework in your app.
For more information on running database migrations see the Heroku docs.

How to add the mode=mysql to embedded H2 DB in Spring Boot 1.4.1 for #DataJpaTest?

I have some problems with using a schema.sql file to create my sql schema when executing a junit test while this schema contains mysql specific expression. I have to add the mode=mysql to the H2 url.
For example something like this:
jdbc:h2:mem:testd;MODE=MYSQL
But Spring boot automatically uses the url defined in the enum
org.springframework.boot.autoconfigure.jdbc.EmbeddedDatabaseConnection with its url
jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE.
I have tried similiar approaches to get this to work, but spring does not take the spring.datasource.url=jdbc:h2:mem:testdb;MODE=MYSQL from my test-application.properties. All other settings from my test-application.properties have been read successfully.
If I let spring/hibernate create the schema (without the schema.sql file) with the javax.persistence annotations in my entities everything works fine.
Is there a simple way to add a mode?
Set
spring.datasource.url=jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE;MODE=MYSQL
in application-test.properties, plus
#RunWith(SpringRunner.class)
#DataJpaTest
#AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
#ActiveProfiles("test")
on the test class
I was having this same issue. It would not pick up the url when running tests. I'm using flyway to manage my scripts. I was able to get all of these working together by following these few steps.
Created a V1_init.sql script in src/test/resources/db/migration so that it is the first script run by flyway.
SET MODE MYSQL; /* another h2 way to set mode */
CREATE SCHEMA IF NOT EXISTS "public"; /* required due to issue with flyway --> https://stackoverflow.com/a/19115417/1224584*/
Updated application-test.yaml to include the schema name public:
flyway:
schemas: public
Ensure the test specified the profile: #ActiveProfiles("test")
I have tried similiar approaches to get this to work, but spring does not take the spring.datasource.url=jdbc:h2:mem:testdb;MODE=MYSQL from my test-application.properties
Did you try to append this parameters instead of rewriting the existing ones?
spring.datasource.url=jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE;MODE=MYSQL
All other settings from my test-application.properties have been read successfully.
I thought that file should be named application-test.properties.
I was able to run it with this config:
# for integration tests use H2 in MySQL mode
spring.datasource.url=jdbc:h2:mem:testdb;DATABASE_TO_LOWER=TRUE;MODE=MySQL;
spring.jpa.database-platform=org.hibernate.dialect.MariaDBDialect
The main trick here is to force Hibernate to generate SQL scripts for MariaDB dialect because otherwise Hibernate tries to use H2 dialect while H2 is already waiting for MySQL like commands.
Also I tried to use more fresh MariaDB103Dialect for MariaDB 10.3 but it doesn't worked properly.
You need to set MYSQL mode on h2 and disable replacing of datasource url for embedded database:
Modify application-test.yaml
spring:
datasource:
url: jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=false;MODE=MYSQL
test:
database:
replace: NONE

Categories

Resources