为啥带有嵌入式 H2 的 Spring Boot 会抛出“org.h2.message.DbException”错误?

Posted

技术标签:

【中文标题】为啥带有嵌入式 H2 的 Spring Boot 会抛出“org.h2.message.DbException”错误?【英文标题】:Why does Spring Boot with embedded H2 throw a 'org.h2.message.DbException' error?为什么带有嵌入式 H2 的 Spring Boot 会抛出“org.h2.message.DbException”错误? 【发布时间】:2020-11-09 17:34:48 【问题描述】:

我正在 MacBook 上使用 Eclipse/STS 做一个简单的 Spring Boot 和嵌入式 H2 教程。

当我只使用 H2 作为内存时它工作正常,我的 application.properties 文件如下所示:

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

但我想将数据库持久化到一个文件中(这样应用程序关闭时数据不会丢失)。

当我进行此更改以将 DB 写入磁盘时:

spring.datasource.url=jdbc:h2:file:/data/demo

我在启动时收到此错误:

org.h2.message.DbException: Log file error: "/data/demo.trace.db", cause: "org.h2.message.DbException: Error while creating file ""/data"" [90062-200]" [90034-200]

我做错了什么?

来自堆栈跟踪的更多详细信息:

2020-11-09 12:33:24.246  INFO 15139 --- [  restartedMain] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
org.h2.message.DbException: Log file error: "/data/demo.trace.db", cause: "org.h2.message.DbException: Error while creating file ""/data"" [90062-200]" [90034-200]
org.h2.message.DbException: Log file error: "/data/demo.trace.db", cause: "org.h2.message.DbException: Error while creating file ""/data"" [90062-200]" [90034-200]
    at org.h2.message.DbException.get(DbException.java:194)
    at org.h2.message.TraceSystem.logWritingError(TraceSystem.java:294)

[...]

Caused by: org.h2.jdbc.JdbcSQLNonTransientException: Log file error: "/data/demo.trace.db", cause: "org.h2.message.DbException: Error while creating file ""/data"" [90062-200]" [90034-200]
    at org.h2.message.DbException.getJdbcSQLException(DbException.java:505)
    at org.h2.message.DbException.getJdbcSQLException(DbException.java:429)
    ... 92 more
Caused by: org.h2.message.DbException: Error while creating file "/data" [90062-200]
    at org.h2.message.DbException.get(DbException.java:205)
    at org.h2.message.DbException.get(DbException.java:181)
    at org.h2.store.fs.FilePathDisk.createDirectory(FilePathDisk.java:290)
    at org.h2.store.fs.FileUtils.createDirectory(FileUtils.java:43)
    at org.h2.store.fs.FileUtils.createDirectories(FileUtils.java:315)
    at org.h2.message.TraceSystem.openWriter(TraceSystem.java:305)
    ... 89 more
Caused by: org.h2.jdbc.JdbcSQLNonTransientException: Error while creating file "/data" [90062-200]
    at org.h2.message.DbException.getJdbcSQLException(DbException.java:505)
    at org.h2.message.DbException.getJdbcSQLException(DbException.java:429)
    ... 95 more

【问题讨论】:

乍一看,好像是文件写入磁盘的权限有些问题。 您确定要写信给/data/demo 而不是例如./data/demo(注意.)还是只是data/demo?前者会尝试写入根目录,您的应用程序几乎肯定缺少必要的写入权限。 谢谢@DmitriyPopov——你的权限想法让我更仔细地查看了目录和权限,结果发现问题是我需要带有“.”的“./data/demo” 谢谢@user991710——你是对的,问题是我需要带有“.”的“./data/demo”干杯。 【参考方案1】:

解决方案是我需要一个像这样的. ./data/demo

spring.datasource.url=jdbc:h2:file:./data/demo

【讨论】:

请注意:./ 表示之后的目录或文件相对于应用程序的当前工作目录。对于嵌入式数据库(至少在 Spring 中通常使用 H2),这应该没问题。对于专用数据库,您将拥有一个完全限定的 JDBC 字符串,它是正在侦听传入连接的 DBMS 的地址。

以上是关于为啥带有嵌入式 H2 的 Spring Boot 会抛出“org.h2.message.DbException”错误?的主要内容,如果未能解决你的问题,请参考以下文章

H2 嵌入式数据库在 Spring Boot 测试期间未获取属性

Spring Boot with H2 每次 web 应用启动时都会运行 data.sql,这正常吗?

spring Boot 整合H2+Mybatis环境搭建

为啥 H2 进行 spring-boot 测试,但它会将数据写入我的本地 mysql 数据库?

Flyway 与 Spring Boot 的集成不会在嵌入式 H2 数据库上执行迁移脚本

Spring-Boot / H2 将数据库快照写入文件系统