无法在 h2 内存数据库中插入数据

Posted

技术标签:

【中文标题】无法在 h2 内存数据库中插入数据【英文标题】:cannot insert data in h2 in-memory database 【发布时间】:2019-07-25 06:48:05 【问题描述】:

我在 inMemory 数据库中插入数据,在插入数据时遇到问题,

使用 boot、JPA、H2db 在 inMemory 中插入数据的示例程序

创建 Pojo 并使用 JPA 注释进行注释

为查询创建 data.sql 文件。

运行应用程序。 请在屏幕截图中找到问题详细信息。

我尝试了很多方法,但仍然是同样的例外

在 app.prop 中配置:String url = jdbc:h2:~/test;DB_CLOSE_ON_EXIT=FALSE

在 data.sql 文件中为给定表添加了@Table

添加了@Column 用于转换的名称,如 data.sql 中所述。

在哪里配置; DB_CLOSE_ON_EXIT=FALSE 在 springboot 中?

POJO

@Entity
@Table(name = "exchange_value")
public class CurrencyExchange 
    @Id
    private Long id;
    @Column(name = "currency_from")
    private String from;
    @Column(name = "currency_to")
    private String to;
    @Column(name = "conversion_multiple")
    private BigDecimal conversion;
    private int port;

控制器

@Autowired
    private Environment env;
    @GetMapping("/currency-exchange/from/from/to/to")
    public CurrencyExchange retriveCurrencyExchange(@PathVariable String from,@PathVariable String to)
    
        CurrencyExchange currencyExchange = new CurrencyExchange(1000L, from, to, BigDecimal.valueOf(65));
        currencyExchange.setPort(Integer.parseInt(env.getProperty("local.server.port")));
        return currencyExchange;

    


app.prop

spring.application.name=currency-exchange-service
server.port=8000

spring.jpa.show-sql=true
spring.h2.console.enabled=true

data.sql file



 insert into exchange_value(id,currency_from,currency_to,conversion_multiple,port)
    values(1001,'USD','INR',65,0);
    insert into exchange_value(id,currency_from,currency_to,conversion_multiple,port)
    values(1002,'EUR','INR',75,0);

Output: The data should be inserted into in-memory database while hitting the service. 

错误原因: 在名为“inMemoryDatabaseShutdownExecutor”的 bean 上调用 destroy 方法失败:org.h2.jdbc.JdbcSQLNonTransientConnectionException:数据库已关闭(要在 VM 关闭时禁用自动关闭,请将“;DB_CLOSE_ON_EXIT=FALSE”添加到 db URL)[90121-199 ] org.springframework.beans.factory.BeanCreationException:在类路径资源[org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]中定义名称为“entityManagerFactory”的bean创建错误:bean初始化失败;嵌套异常是 org.springframework.jdbc.datasource.init.ScriptStatementFailedException:无法执行 URL [file:/Users/naresh/Documents/workspace-sts-3.9.8.RELEASE/currency-exchange-service 的 SQL 脚本语句#1 /target/classes/data.sql]:插入 exchange_value(id,currency_from,currency_to,conversion_multiple,port) values(1001,'USD','INR',65,0);嵌套异常是 org.h2.jdbc.JdbcSQLSyntaxErrorException:找不到表“EXCHANGE_VALUE”; SQL 语句: 插入 exchange_value(id,currency_from,currency_to,conversion_multiple,port) 值(1001,'USD','INR',65,0) [42102-199] org.h2.jdbc.JdbcSQLSyntaxErrorException:找不到表“EXCHANGE_VALUE”; SQL 语句: 插入 exchange_value(id,currency_from,currency_to,conversion_multiple,port) 值(1001,'USD','INR',65,0) [42102-199]

【问题讨论】:

错误提示EXCHANGE_VALUE 表不存在 【参考方案1】:

改变

String url = jdbc:h2:~/test;DB_CLOSE_ON_EXIT=FALSE

spring.datasource.url: 'jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1'

application-properties

另外,在插入记录之前,请确保 Table exchange_value 存在(您已经编写了用于创建表的 SQL)

要保持数据库打开,请将 ;DB_CLOSE_DELAY=-1 添加到数据库 URL。 将内存数据库的内容与虚拟数据库一样长 机器还活着,使用 jdbc:h2:mem:test;DB_CLOSE_DELAY=-1。

H2 Database


更新

创建 2 个 sql 文件。一个用于创建 Schema,另一个用于插入记录

application.properties

spring.datasource.url=jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect


# Enabling H2 Console
spring.h2.console.enabled=true

# Custom H2 Console URL
spring.h2.console.path=/h2


更新 2

是的,Spring Boot 可以为您自动创建表,确保您拥有 @Table(name = "TableName")spring.jpa.hibernate.ddl-auto=createspring.jpa.hibernate.ddl-auto=update

实体

@Entity
@Table(name="exchange_value")
public class ExchangeValueEntity 
   //some fields

application.properties

spring.jpa.hibernate.ddl-auto=create

【讨论】:

我尝试添加 spring.datasource.url: 'jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1',仍然面临同样的错误。问题:我需要在 Spring Boot 中在哪里运行脚本? 你好@AbdulWajeed 在插入记录之前确保你已经创建了表 EXCHANGE_VALUE 并告诉我 请告诉我,在启动时我需要在哪里创建脚本?正如我所说,我使用的是 H2 的 inMem DB。 我们可以把sql文件放到resources文件夹(/src/main/resources/) @AbdulWajeed 请查看更新后的答案,如果它不起作用,请分享您的全部 application.propertiesproject structure【参考方案2】:

这行得通

spring.application.name=currency-exchange-service
server.port= 8000
spring.datasource.url=jdbc:h2:mem:testdb
spring.h2.console.enabled=true
spring.jpa.hibernate.ddl-auto=update

【讨论】:

欢迎来到 Stack Overflow。没有任何解释的代码很少有帮助。 Stack Overflow 是关于学习的,而不是提供 sn-ps 来盲目复制和粘贴。请编辑您的问题并解释它如何回答所提出的具体问题。见How to Answer。 啊!将ddl-autocreate-drop 更改为update 有效;现在我的数据被插入到表中;以前,我只创建表。我不知道为什么,但谢谢。 vladmihalcea.com/hibernate-hbm2ddl-auto-schema根据这里,也许我使用create-drop时插入sql没有执行?我的sql包括drop all objects; create schema; create table ...insert into ...【参考方案3】:

确保您在资源文件夹中提供了 data.sql。

【讨论】:

【参考方案4】:

确保:

ddl-auto 设置为update;不知何故,只有这样才允许数据插入 并在要运行的脚本中,记住drop all objects; create schema...; set schema ...作为第一步;这每次都会初始化数据库 并包含创建表和插入数据的sql

【讨论】:

以上是关于无法在 h2 内存数据库中插入数据的主要内容,如果未能解决你的问题,请参考以下文章

内存 H2 数据库,插入脚本不持久

内存模式下的H2数据库无法被Console访问

如何将格式为“3/22/2018 12:24:29 PM”的日期时间字符串格式化为sql时间戳以插入内存数据库中的h2?

与内存数据库中的同一个 H2 建立多个连接[重复]

在同一应用程序中使用内存中的 H2 和 H2 文件

H2 内存数据库未在 weblogic 中显示控制台,但在 Tomcat 中显示