Spring boot - h2 and Oracle no 100% compatibility - spring

I am using H2 in Spring boot app and Oracle DB on production.
For checking migration files I use FlyWay.
Unfortunately, H2 isn't compatible with Oracle (even if is set Oracle mode).
So, I can't validate my migrations files.
When I have a H2 query - validation in my project is ok, but when I upload it to production - it won`t work on Oracle.
Have you got any ideas how can I validate oracle migration files on my h2-db project?

The Flyway FAQ covers this under db specific SQL:
You can use the flyway.locations property. It would look like this:
TEST (Derby): flyway.locations=sql/common,sql/derby
PROD (Oracle): flyway.locations=sql/common,sql/oracle
You could then have the common statements (V1__Create_table.sql) in common and different copies of the DB-specific statements (V2__Alter_table.sql) in the db-specific locations.
Another approach if the differences are really minor ie only a few keywords, would be to have the keywords that differ as Flyway placeholders:
ALTER TABLE table_name ${alter_column} COLUMN column_name datatype;
TEST (H2): flyway.placeholders.alter_column=ALTER
PROD (Oracle): flyway.placeholders.alter_column=MODIFY

Related

Spring boot app connecting to 2 H2 databases

In production, my app will need to talk to two different relational databases from different vendors (for example DB2 and MySQL or Oracle)
For development, I intend to use H2 databases to represent the two used in production.
For example TableA is what will be in DB2 and TableB will be in Oracle.
How to configure H2 this way so it knows that JPA/Hibernate generates TableA for DB2 AND TableB for Oracle?
You can separate your application into two apps. Then use restTemplate to get data from one app to another.
So in dev mode use h2 in each app.

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

spring boot hsqldb details

I have created two spring boot microservices for experimenting purposes, both use hsqldb. Is there a way to see the hsqldb details like what is the name of the db that spring boot created, username, password, what tables are there in each one and to query those tables.
You can use the built-in SQL functions and INFORMATION_SCHEMA views in HSQLDB to check these properties. See the Guide http://hsqldb.org/doc/2.0/guide/
But the quick and easy way is to use a file: database connection and check the *.script file of the database, which contains SQL statements that set the properties and create the tables.

Table not found after apparently successful migration

I was using flyway through the CL to migrate my production DB (mySql), while I was using a fixed SQL query to create the DB, tables, etc. in my unit tests, using H2. I'd like now to better integrate flyway and create/delete DB after each unit test.
I have a DB factory and inside its build method I'm using the following code:
flyway.setLocations("filesystem:sql/migrations/common","filesystem:sql/migrations/h2");
flyway.setSchemas("MYSERVER");
flyway.setDataSource(
p.getProperty(DB_URL.getName()),
p.getProperty(USERNAME.getName()),
p.getProperty(PASSWORD.getName()));
flyway.setInitOnMigrate(true);
flyway.migrate();
The migrations seems to apply correctly, as I can see my SQL code from the flyway logs. But when I start using the DB, immediately afterwards, I get TABLE NOT FOUND errors. I'm using h2 as in memory DB with the following URL to initialize my client:
jdbc:h2:mem:MYSERVER;MVCC=true
Do you have any idea on what I might be making wrong?
The problem is your JDBC url.
MYSERVER is the name of the database, not the schema.
The easiest thing to do is to let flyway use the same url, and not set a schema. This way you'll find everything in the public schema of the MYSERVER database.
Having the same issue - after digging around, it appears that the H2 database is being recreated between migration scripts somehow.
You can confirm this happens by putting a SELECT * FROM migrations in the first two migrations - it will succeed in the first and fail in the second.
According to the H2 Documentation, specifying a database name and ;DB_CLOSE_DELAY=-1 option should suffice to allow concurrent and subsequent accesses to the in-memory database, however this is not the case.
Upgrading Flyway from 3.1 to 3.2.1 has fixed the problem.

HSQLDB ROWNUM compatibility with Oracle

THe HSQLDB changelog states that ROWNUM() was added in v2.2.0 which I am using without any problems when running integration tests against the in-memory HSQLDB.
However I want to run the same tests against a real Oracle 10g database, but the query fails because the pseudo-column is called ROWNUM. Is there an easy way write a single query string that works in both environments?
The ROWNUM() function is available by default in HSQLDB 2.2.x and later. If you enable Oracle syntax compatibility mode, you can also use ROWNUM.
This statement enables it:
SET DATABASE SQL SYNTAX ORA TRUE
Or use the connection property sql.syntax_ora=true

Resources