How to generate .data file with Spring Boot and HSQLDB - spring-boot

I Use a Spring Boot 2 with file based HSQLDB. This are my properties
spring.datasource.driver-class-name=org.hsqldb.jdbc.JDBCDriver
spring.datasource.url=jdbc:hsqldb:file:${user.dir}/src/main/resources/userdb
spring.jpa.database-platform=org.hibernate.dialect.HSQLDialect
spring.datasource.username=sa
spring.datasource.password=
spring.jpa.hibernate.ddl-auto=update
After application start I use that DB and add some Elements into it. Everything works, after that I expect under the path src/main/resources/ following files.
userdb.log (exists)
userdb.properties (exists)
userdb.script (exists)
userdb.data (where is this?)
But userdb.data is not there, after application restart all data are gone. Userdb.script contains all INSERT commands of data I added but there is no .data file. How to configure Spring Boot to create a userdb.data file and use this with content after restart.
In short, I want a persistent HSQLDB.

The database you've already got is persistent and is fine for small (a few megabytes) data.
The .data file is created when you execute CREATE CACHED TABLE statements or when you specify the default table type to be CACHED.
spring.datasource.url=jdbc:hsqldb:file:${user.dir}/src/main/resources/userdb;hsqldb.default_table_type=cached
See the Guide: http://hsqldb.org/doc/2.0/guide/dbproperties-chapt.html#dpc_db_operations

Related

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

Why H2 file database data get cleared every time

I use H2 database for a test application, using Spring boot. Every time, when I restart the spring boot app, the data in H2 gets cleared. I am using a file instead of memory. I set the spring.jpa.hibernate.ddl-auto=update in application.properties too.
Here is my application.properties file
spring.datasource.url=jdbc:h2:file:./data/demo
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=password
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
spring.h2.console.enabled=true
spring.jpa.hibernate.ddl-auto=update
What am I doing wrong here. It saves data fine. But once I shut down the app, all data get cleared.
I found the mistake I was doing. I had data.sql file in resources and every time Spring boot starts the app, it runs this script. In that script I was dropping and recreating all the tables. Once I removed those sql statements, it works perfect. Data is persistent to the file and won't be erased after the server restart.
By default, closing the last connection to a database closes the database. For an in-memory database, this means the content is lost. To keep the database open, add ;DB_CLOSE_DELAY=-1 to the database URL. To keep the content of an in-memory database as long as the virtual machine is alive, use jdbc:h2:mem:test;DB_CLOSE_DELAY=-1.; DB_CLOSE_ON_EXIT=FALSE;
H2 Feature Document

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

Setting up multiple database with Flyway

I am trying to setup two different database with Flyway 5.0.7, MySQL for development and H2 for testing. I have configured both databases in respective files.
For Development, src/main/resource/application.properties
spring.datasource.url=jdbc:mysql://localhost:3306/moment
spring.datasource.username=root
spring.datasource.password=root
flyway.locations=db/migration,db/specific/mysql
For Testing, src/test/resource/application.properties
spring.datasource.driver-class-name=org.h2.Driver
spring.datasource.url=jdbc:h2:mem:db;DB_CLOSE_DELAY=-1
spring.datasource.username=sa
spring.datasource.password=sa
flyway.locations=db/migration,db/specific/h2
Below is the folder structure for Flyway migration files
In this case Flyway is not able to find migration files under specific folder and throws error when applying V1.1__Insert_Records.sql for table not found.
If I move the specific folder inside db/migration, I am getting error for duplicate files of same version.
Any suggestions how should I configure migration files for multiple databases to work with Flyway?
I suspect you might be using Spring Boot 2.x here? If so, flyway.locations is no longer valid and will be ignored.
Flyway will then just use the default location (db/migration), which will find only the V1.1__Insert_Records.sql script but not the V1__Create_table.sql script.
With Spring Boot 2.x, flyway.locations must be prefixed with spring.:
spring.flyway.locations=db/migration,db/specific/h2
By the way, if you use the {vendor} placeholder in the location, Spring Boot will work out the directory from the lowercase of the database driver id (h2, mysql, oracle, etc), which is nice:
spring.flyway.locations=db/migration,db/specific/{vendor}

How to pass database name explicitly in Spring Boot Configuration?

I've a Spring Boot application of mine, which connects to a Postgres database. I've specified in application.properties the datasource url as -
spring.datasource.url=jdbc:postgresql://< server ip here >:5432/mydb
The jdbc url (jdbc:postgresql://< server ip here >:5432/) is actually stored in a separate external location which my application is able to read. Therefore, I want to specify only the database name in my properties file.
I don't want to pass the database name as some environment variable since it's not going to change.
I'm stuck at this point for quite some time now, how can I achieve the same?
Add this in your application.properties file
spring.jpa.hibernate.ddl-auto=create\update\none
spring.datasource.url=jdbc:postgresql://host:port/db
spring.datasource.username=username
spring.datasource.password=password
Have you tried using ${var} syntax like:
spring.datasource.url=jdbc:postgresql://${server-ip}:5432/mydb
See:
https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html#boot-features-external-config-application-property-files
https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html#boot-features-external-config-placeholders-in-properties
I finally implemented it this way.
Specified only database name in my application and created Datasource bean in a separate Spring Boot application (so that it can be reused across other projects as well).

Resources