jHipster - Loading data - h2

Is there a workflow for adding data with jHipster?
I want to add static data for the H2 database in the first instance, is this process different when using MySql, postgresql?
I note there is a users.csv which is loaded via liquibase, I'm guessing I create another csv and load that.
Cheers..

It's the same for all SQL databases as it uses Liquibase, you must create a Liquibase changelog that uses loadData to load your CSV file from src/main/resources/config/liquibase/data and refer to it from master.xml.
Additionally, you can also tag your changelog so that this data is only loaded for H2 by setting a conditional dbms="h2" or use a condition on Liquibase context context="dev" that you can then set in application*.yml.

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.

How should I control order of execution between Liquibase and springboot data.sql?

We have a (internal to company, external to project) library (jar) that includes some Liquibase scripts to add tables to a schema to support the functionality of that library.
Using SpringBoot and Maven to run integration tests with H2, we have been using sql files, listed in property files, to initialise the DB.
We want to be able to add data to the tables created by the external (to the project) library for the ITs but finding the tables haven't been created by Liquibase when SpringBoot/SpringData attempts to run the insert statements in our sql files.
Given the errors we're seeing (tables not existing when spring attempts to run the insert.sql files) it looks like spring is executing those files before Liquibase has done its thing.
How can I ensure Liquibase config run by the library to create tables has completed before Spring does it's thing with running sql files specified by the spring.datasource.data property?
We don't really want to include the test data in the library (which was working, but introduced other issued we are trying to work around with liquibase inserting test data into production DB).
what about using different context for your tests?
so you will have application.properties in your test folder and there you will define another changelog that will include all changelogs that are needed (even from library) and you will also include the .sql file that you are running probably with jpa? Try to look here if that helps.

How to disable loading schema.sql if database already exists?

I am using H2 database stored in a file and schema.sql script to initialize the database (using DatabasePopulator class in Spring). It works, but schema.sql is imported every time the application starts (establishes a connection).
My goal is to load it after database creation only. If a connection is established to already existing database, I want to skip it.
From what I've read:
H2 provides a way to init database using RUNSCRIPT in jdbc url (loads every time, not what I want).
Spring Data JPA and Hibernate allow database initialization by autogenerating DDL (not what I want, I have to use schema.sql) or loading schema.sql, but that one only works when spring.jpa.hibernate.ddl-auto property is set to either create or create-drop, which is also not what I want, because I have database in a file and it must not be deleted every time the application starts.
So my question is: How to load schema.sql on database creation only, without manually checking if the database exists? Is it even possible?

How to insert data to table on spring boot application start?

How can I insert data to a table on Spring Boot application start? My application is generated by JHipster. What I need to check is that if that particular data already exist in that table or not. If it doesn't I should add it.
If your application was generated by JHipster, then it should already include and be properly configured for Liquibase.
You have a few options:
You can use Liquibase's insert change to insert data.
You can put your data in a CSV file and use the loadData change to load it. Look for the loadData tag in 00000000000000_initial_schema.xml for examples.
You can use the sql change to run native SQL directly.
All three options can be combined with preconditions to make sure the data doesn't exist before trying to insert it. If you need the changeset to run every time you boot your application, you can use the runAlways="true" attribute (docs for that are on this page).
You can create a function in your service class which checks if the data already exists or not and if not then save that data.
You can implement an ApplicationRunner and use a repository to do whatever you need to do.
If the ApplicationRunner is a spring bean it is run on application startup.
For more sophisticated requirements I would try to rely on a tool like flyway that has good integration with spring boot

HSQL Unit Test -- How to Create Multiple In-Memory Schemas?

I would like to use hsql within my DAO unit tests for a web application. The web app is written against mysql and uses three different schemas within the same mysql database. Some schemas has FK relationships with data in the other schemas. If I'm to unit test, I must be able to execute against a database that can hold multiple schemas.
I know that HSQL supports multiple schemas, but I don't know how to configure hsql to have multiple schemas set up for an in-memory database. I read that I can define multiple schemas in the server.properties file, but the file needs to be in the location of where the java class was called -- the junit.jar location? If so, that would be hard to support in my Java Maven application. How can I:
Run an in-memory hsql database to start up with three databases?
Where would I place the server.properties file in my Maven app?
Could I point hsql to use a server.properties file in a location other than where the junit jar is (that's a showstopper for me)?
Is it possible to configure multiple schemas for an in-memory database just via a tricked out jdbc url?
I wish I could untangle the schemas from each other, but that's not possible at this time.
Thanks for your help!
HSQLDB supports multiple schemas in the same database. Foreign keys can reference tables from different schemas. The following apply to the very latest HSQLDB 2.2.6 snapshot available from http://hsqldb.org
Before running your tests, execute CREATE SCHEMA schemaname for each schema.
Doesn't matter where, you can specify the absolute path on the command line arguments when running. See the HSQLD Guide and JavaDoc on server.
Yes.
No. You use the SQL statement to create the schemas.
Note you have two options for running HSQLDB, one is as a server, the other is as an embedded database. In the case of server, it must be started before the test run. In both cases, you need to connect to the database and create the schemas before your tests.
It is possible to create different db by setting db name. By default, it creates the db name as testdb, but in case we want to create multiple db, then set the name explicitly.
new EmbeddedDatabaseBuilder()
.setType(EmbeddedDatabaseType.HSQL).setName("DB_NAME")
.addScript("DDL.SQL")
.addScript("DML.SQL")
.build();
If you run the below line mutiple time, you can see the databases:
DatabaseManagerSwing.main(new String[] { "--url", "jdbc:hsqldb:mem:" + dbnaes, "--user", "sa", "--password", "" });

Resources