I have successfully created a spring boot application that uses the H2 embedded database in-memory. I would now like to change this to a file based version that will persist.
I have tried just changing the spring.datasource.*
properties in my application.properties
file and they look something like this:
spring.datasource.url=jdbc:h2:file:~/test;DB_CLOSE_ON_EXIT=FALSE
spring.datasource.username=test
spring.datasource.password=test
spring.datasource.driverClassName=org.h2.Driver`
It seems like spring boot just ignores these settings because it just starts as follows:
o.s.j.d.e.EmbeddedDatabaseFactory : Starting embedded database: url='jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=false', username='sa'
My pom.xml
contains the following dependencies that may be relevant to this post:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.3.5.RELEASE</version>
</parent>
....
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>
My understanding from the documentation and a number of posts is that the configuration should just work but no luck for me. Just to prevent some of the basic errors I have tried and checked the following:
@EnableAutoConfiguration
dataSource
bean with combinations of annotation @Primary
, @ConfigurationProperties(prefix = "spring.datasource")
and setting the properties programmatically with DataSourceBuilder
. This causes other errors related to the type being null
. Seems like I am missing a key concept or something. Can anyone help.
UPDATE 1: Extract from my auto configuration report:
Positive matches:
-----------------
DataSourceAutoConfiguration matched
- @ConditionalOnClass classes found: javax.sql.DataSource,org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType (OnClassCondition)
DataSourceAutoConfiguration.DataSourceInitializerConfiguration matched
- @ConditionalOnMissingBean (types: org.springframework.boot.autoconfigure.jdbc.DataSourceInitializer; SearchStrategy: all) found no beans (OnBeanCondition)
DataSourceAutoConfiguration.EmbeddedConfiguration matched
- embedded database H2 detected (DataSourceAutoConfiguration.EmbeddedDataSourceCondition)
- @ConditionalOnMissingBean (types: javax.sql.DataSource,javax.sql.XADataSource; SearchStrategy: all) found no beans (OnBeanCondition)
DataSourceAutoConfiguration.JdbcTemplateConfiguration matched
- existing auto database detected (DataSourceAutoConfiguration.DataSourceAvailableCondition)
DataSourceAutoConfiguration.JdbcTemplateConfiguration#jdbcTemplate matched
- @ConditionalOnMissingBean (types: org.springframework.jdbc.core.JdbcOperations; SearchStrategy: all) found no beans (OnBeanCondition)
DataSourceAutoConfiguration.JdbcTemplateConfiguration#namedParameterJdbcTemplate matched
- @ConditionalOnMissingBean (types: org.springframework.jdbc.core.namedparam.NamedParameterJdbcOperations; SearchStrategy: all) found no beans (OnBeanCondition)
DataSourceTransactionManagerAutoConfiguration matched
- @ConditionalOnClass classes found: org.springframework.jdbc.core.JdbcTemplate,org.springframework.transaction.PlatformTransactionManager (OnClassCondition)
DataSourceTransactionManagerAutoConfiguration.TransactionManagementConfiguration matched
- @ConditionalOnMissingBean (types: org.springframework.transaction.annotation.AbstractTransactionManagementConfiguration; SearchStrategy: all) found no beans (OnBeanCondition)
H2ConsoleAutoConfiguration matched
- @ConditionalOnClass classes found: org.h2.server.web.WebServlet (OnClassCondition)
- found web application StandardServletEnvironment (OnWebApplicationCondition)
- matched (OnPropertyCondition)
HibernateJpaAutoConfiguration matched
- @ConditionalOnClass classes found: org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean,org.springframework.transaction.annotation.EnableTransactionManagement,javax.persistence.EntityManager (OnClassCondition)
- found HibernateEntityManager class (HibernateJpaAutoConfiguration.HibernateEntityManagerCondition)
Negative matches:
-----------------
DataSourceAutoConfiguration.NonEmbeddedConfiguration did not match
- missing supported DataSource (DataSourceAutoConfiguration.NonEmbeddedDataSourceCondition)
`
UPDATE 2: added actuator and looked at endpoint /configprops
. What is interesting here is that my config has been taken and the database exists but when the application runs it does not use this dataSource
.
"spring.datasource.CONFIGURATION_PROPERTIES":
{"prefix":"spring.datasource",
"properties":{
"schema":null,
"data":null,
"xa":{"dataSourceClassName":null,
"properties":{}
},
"type":null,
"separator":";",
"url":"jdbc:h2:file:~/test;DB_CLOSE_ON_EXIT=FALSE",
"platform":"all",
"continueOnError":false,
"jndiName":null,
"sqlScriptEncoding":null,
"password":"******",
"name":"testdb",
"driverClassName":"org.h2.Driver",
"initialize":true,
"username":"test"
}
}
I am adding this answer to avoid confusion and further research.
Actually I have the same problem and none of the answer worked for me completely rather than the mix for some answers worked.
Here is the minimal configuration which is required to persist H2 db in spring boot.
application.properties
# H2
spring.h2.console.enabled=true
spring.h2.console.path=/h2
# Datasource
spring.datasource.url=jdbc:h2:file:~/spring-boot-h2-db
spring.datasource.username=sa
spring.datasource.password=
spring.datasource.driver-class-name=org.h2.Driver
spring.jpa.hibernate.ddl-auto=update
Here spring.jpa.hibernate.ddl-auto=update
does the trick. Nothing else is required.
No need to add spring-boot-starter-jdbc
in pom.xml
No need to add any parameter in jdbc url.