简体   繁体   English

如何配置 spring-boot 以使用基于文件的 H2 数据库

[英]How to configure spring-boot to use file based H2 database

I have successfully created a spring boot application that uses the H2 embedded database in-memory.我已经成功创建了一个使用内存中 H2 嵌入式数据库的 Spring Boot 应用程序。 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:我尝试只更改application.properties文件中的spring.datasource.*属性,它们看起来像这样:

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:似乎 spring boot 只是忽略了这些设置,因为它只是按如下方式开始:

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:我的pom.xml包含以下可能与这篇文章相关的依赖项:

<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:只是为了防止一些基本错误,我尝试并检查了以下内容:

  1. My application properties is in the classspath:我的应用程序属性在类路径中:
  2. I have tried to exclude the auto configuration in annotation @EnableAutoConfiguration我试图在注释@EnableAutoConfiguration中排除自动配置
  3. I have tried to inject a dataSource bean with combinations of annotation @Primary , @ConfigurationProperties(prefix = "spring.datasource") and setting the properties programmatically with DataSourceBuilder .我试图注入带有注释@Primary@ConfigurationProperties(prefix = "spring.datasource")组合的dataSource bean,并使用DataSourceBuilder以编程方式设置属性。 This causes other errors related to the type being null .这会导致与类型相关的其他错误为null

Seems like I am missing a key concept or something.好像我错过了一个关键概念或其他东西。 Can anyone help.任何人都可以帮忙。

UPDATE 1: Extract from my auto configuration report:更新 1:从我的自动配置报告中提取:

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 .更新 2:添加执行器并查看端点/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 .这里有趣的是我的配置已经被采用并且数据库存在但是当应用程序运行时它不使用这个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.这是在 Spring Boot 中持久化 H2 db 所需的最小配置。

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.这里spring.jpa.hibernate.ddl-auto=update可以解决问题。 Nothing else is required.没有其他要求。

No need to add spring-boot-starter-jdbc in pom.xml无需在 pom.xml 中添加spring-boot-starter-jdbc

No need to add any parameter in jdbc url.无需在 jdbc url 中添加任何参数。

Refer to http://www.h2database.com/html/cheatSheet.html参考http://www.h2database.com/html/cheatSheet.html

I guess it might be problem with the jdbc.url, change it like this:我想这可能是 jdbc.url 的问题,像这样更改它:

# from:
spring.datasource.url=jdbc:h2:file:~/test;DB_CLOSE_ON_EXIT=FALSE

# to:
spring.datasource.url=jdbc:h2:~/test;DB_CLOSE_ON_EXIT=FALSE

Using the following setting on application.properties, I manage to keep the data persisted even after shutting down and restarting SpringBoot, and even after restarting the computer.使用 application.properties 上的以下设置,即使在关闭并重新启动 SpringBoot,甚至在重新启动计算机之后,我也设法保持数据保持不变。

spring.datasource.name=japodb
spring.datasource.initialize=false
spring.datasource.driverClassName=org.h2.Driver

spring.datasource.url=jdbc:h2:file:~/japodb;DB_CLOSE_ON_EXIT=FALSE;IFEXISTS=TRUE;DB_CLOSE_DELAY=-1;

Don't Close a Database when the VM Exits , yes, but also don't make a new database if it's already there.虚拟机退出时不要关闭数据库,是的,但如果它已经存在,也不要创建新数据库。

jdbc:h2:<url>;IFEXISTS=TRUE

spring.jpa.hibernate.ddl-auto = update

Here is the configuration worked for me这是对我有用的配置

#File based h2 DB
spring.datasource.url=jdbc:h2:file:C:/temp/test_db;DB_CLOSE_ON_EXIT=FALSE;AUTO_RECONNECT=TRUE;DB_CLOSE_DELAY=-1
#In memory
#spring.datasource.url=jdbc:h2:mem:testdb:security_permission;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE
spring.datasource.driverClassName=org.h2.Driver
spring.h2.console.enabled=true
spring.h2.console.path=/h2-console
spring.jpa.hibernate.ddl-auto=update
spring.datasource.username=user
spring.datasource.password=admin
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
#Use datasource.initialization-mode if you are configured to use file based h2 and data.sql
spring.datasource.initialization-mode=always
spring.jpa.defer-datasource-initialization=true

When I used data initialization with data.sql, I have to use the following option to make it work当我使用 data.sql 进行数据初始化时,我必须使用以下选项才能使其工作

spring.datasource.initialization-mode=always

After the data is initialized, it can be set to never数据初始化后,可以设置为从不

spring.datasource.initialization-mode=never

Just generated a brand new Spring Boot project with start.spring.io with a few dependencies h2, JPA, web, devtools, actuator .刚刚使用 start.spring.io 生成了一个全新的 Spring Boot 项目,其中包含一些依赖项h2, JPA, web, devtools, actuator After adding a simple Entity and Spring Data repository, the database is indeed created in memory by default.添加一个简单的 Entity 和 Spring Data 存储库后,数据库确实默认创建在内存中。

Adding the following to my application.properties definitely creates the database file in the right place:将以下内容添加到我的application.properties肯定会在正确的位置创建数据库文件:

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

I can even connect to it with the H2 console when devtools is enabled http://localhost:8080/h2-console/ .当 devtools 启用http://localhost:8080/h2-console/时,我什至可以使用 H2 控制台连接到它。

The next logical step is to visit the http://localhost:8080/autoconfig endpoint and check the auto-configuration status.下一个合乎逻辑的步骤是访问http://localhost:8080/autoconfig端点并检查自动配置状态。

In my case, the following is positiveMatches :就我而言,以下是positiveMatches

DataSourceAutoConfiguration.NonEmbeddedConfiguration: [
{
  condition: "DataSourceAutoConfiguration.NonEmbeddedDataSourceCondition",
  message: "supported DataSource class found"
},
{
  condition: "OnBeanCondition",
  message: "@ConditionalOnMissingBean (types: javax.sql.DataSource,javax.sql.XADataSource; SearchStrategy: all) found no beans"
}
],

and the following in negativeMatches :以及negativeMatches中的以下内容:

DataSourceAutoConfiguration.EmbeddedConfiguration: [
{
  condition: "DataSourceAutoConfiguration.EmbeddedDataSourceCondition",
  message: "existing non-embedded database detected"
}
],

Could you try the following and check the auto-configuration report for those?您可以尝试以下方法并检查这些自动配置报告吗?

Create a file .h2.server.properties in your class path and put below things and try again.在您的类路径中创建一个文件.h2.server.properties并将其放在下面,然后重试。 You can create this file in resources folder.您可以在资源文件夹中创建此文件。

#H2 Server Properties
0=H2 File|org.h2.Driver|jdbc\:h2\:file\:~/test;DB_CLOSE_ON_EXIT=FALSE

# Enable if you want other applications to connect
#webAllowOthers=true
#webPort=8082
#webSSL=false

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM