Why H2 file database data get cleared every time - spring-boot

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

Related

How to generate .data file with Spring Boot and HSQLDB

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

(Spring Boot and H2) Can't use h2 database

I'm learning Spring boot and I'm trying to create a very simple RESTful API that access an in-memory database and perform CRUD actions.
However, everytime I try to Connect or Test Connection on http://localhost:8080/h2-console, I get this error:
"Database "C:/Users/XXX/test" not found, and IFEXISTS=true, so we cant auto-create it [90146-199] 90146/90146"
https://imgur.com/a/oYgkK1C
I followed EXACTLY the instructions from http://www.springboottutorial.com/spring-boot-crud-rest-service-with-jpa-hibernate. I have tried everything I could find online: using jdbc:h2:mem:test as JDBC URL etc, but none of them worked for me and I'm not sure what am I doing wrong.
I didn't install h2 database from the official website as I read it is not necessary to use the in-memory module (and I still don't know if I should've installed it or not, as there is not a single mention of it online, as far as I checked).
Any thoughts? I'm a beginner when it comes to Spring Boot and I'm really lost. I just want to test CRUD actions and I don't care about the persistence of the DB.
I have provided my application.properties below.
Thank you! :)
# H2
spring.h2.console.enabled=true
spring.h2.console.path=/h2
# Datasource
spring.datasource.url=jdbc:h2:mem:test
spring.datasource.username=user
spring.datasource.password=user
spring.datasource.driver-class-name=org.h2.Driver
Make sure your url in h2-console(refer screenshot below) is same as your 'spring.datasource.url=jdbc:h2:mem:test'.
It worked for me.
UPDATE: Other alternative solution is,
you can avoid setting spring.datasource.url property. Spring will automatically set this default JDBC url for you.
happy learning.. Upvote, if it is sovled your issue.
In your spring application.properties file, set the property
spring.datasource.url=jdbc:h2:~/test
Then restart the application and open http://localhost:8080/h2-console/
Click on Test Connection button, you should see "Test successful".

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?

spring-boot Persistent h2database in filesystem

How can I configure spring-boot with h2database so as it reuses database each time I restart.
This is the only line I have in my application.properties file
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
You have to specify for spring.datasource.url a value that specifies a filesystem DB. You can do it by using the jdbc:h2:file: prefix.
For example, you could use this configuration to store the DB in a mydb.mv.db file in the db folder of your home directory:
spring.datasource.url = jdbc:h2:file:~/db/mydb
Note that spring.jpa.database-platform=org.hibernate.dialect.H2Dialect is not required. The url and the H2 JDBC driver located in the classpath at runtime are enough.
Note also that by default, the database will be automatically created at startup if you use an embedded database (H2, HSQL or Derby).
It is the case even if you specify a file as database in the JDBC URL.
So to avoid recreating the db at each Spring Boot startup, you should also add :
spring.jpa.hibernate.ddl-auto = update
or
spring.jpa.hibernate.ddl-auto = validate

H2 databse to load data only once, but on app ending not to drop data

I gave a spring boot application that uses an embedded H2. What i need is on the first start of the application, to load the data form the data.sql. Every time the application ends, or breaks, the data should be maintained. The reason for this, is that i deploy my application on heroku, which for free use, sleeps after 30 minutes.
You have to use the database in embedded mode. See here.
So your datasource url have to be something like this:
spring.datasource.url=jdbc:h2:~/myDbFile;DB_CLOSE_ON_EXIT=FALSE
You can make your data.sql load conditionally and use a file H2 database see https://www.javatips.net/blog/h2-file-database-example

Resources