将 H2 数据库从 1.4.200 升级到 2.0.204 后的集成测试问题
Problems with integration tests after upgrading H2 database from 1.4.200 to 2.0.204
最近我将 SpringBoot 2.5.8
项目中的 H2
数据库从版本 1.4.200
升级到 2.0.204
。它仅用于测试目的。对于生产,我们使用 PostgreSQL 12.9
。
似乎在升级后某些词成为 H2
数据库中的关键字,例如:day
、value
。调用集成测试后 Hibernate
在 DDL
部分失败。
这种情况的最佳解决方案是什么?
- 查看所有实体并在保留列名称周围应用反引号:
@NotNull
@Column(name = "day", nullable = false)
private LocalDate day;
@NotNull
@Column(name = "`day`", nullable = false)
private LocalDate day;
- 提供专用
SpringPhysicalNamingStrategy
并重写 toPhysicalColumnName
方法仅用于集成测试目的。检查 H2
数据库中的保留关键字列表并引用它们。
# Datasource related properties
spring.datasource.driver-class-name=org.h2.Driver
spring.datasource.url=jdbc:h2:mem:db;DB_CLOSE_DELAY=-1
spring.datasource.username=sa
spring.datasource.password=sa
spring.sql.init.mode=always
spring.sql.init.continue-on-error=true
spring.sql.init.platform=h2
spring.jpa.show-sql=true
spring.jpa.generate-ddl=true
spring.jpa.hibernate.ddl-auto=update
spring.jpa.properties.hibernate.jdbc.time_zone=UTC
spring.jpa.hibernate.naming.physical-strategy=[project-related-package-name-here].strategy.CustomH2NamingStrategy
spring.jpa.defer-datasource-initialization=true
我认为第一个解决方案应该适用于 PostgreSQL
和 H2
数据库。尽管 day
标识符在 PostgreSQL 12.9
中未保留,但可能会出现在未来的版本中。
第二个应该解决 H2
数据库的问题。
你怎么看?对于这种情况,也许有更好的解决方案?或者从 SQL:2016
标准中获取保留关键字列表,并通过自定义 SpringPhysicalNamingStrategy
?
将它们应用于两个数据库
在 H2 2.0 中,您可以通过将 ;NON_KEYWORDS=DAY,VALUE
附加到 JDBC URL 来使用 SET NON_KEYWORDS 设置,但正常的解决方案是在生成的 [=25] 中引用所有标识符=] 无条件地使用 spring.jpa.properties.hibernate.globally_quoted_identifiers=true
,例如。
当您尝试使用 H2 而不是 PostgreSQL 时,您通常还应该在 H2 的 JDBC URL 中包含 ;MODE=PostgreSQL;DATABASE_TO_LOWER=TRUE;DEFAULT_NULL_ORDERING=HIGH
。但是使用不同的 DBMS 进行生产和测试是个坏主意而且 Hibernate ORM 还不完全支持 H2 2.0。已编辑:Hibernate ORM 5.6.5.Final 具有对 H2 2.*.* 的基本支持,并且在较新版本中修复了一些其他问题。
最近我将 SpringBoot 2.5.8
项目中的 H2
数据库从版本 1.4.200
升级到 2.0.204
。它仅用于测试目的。对于生产,我们使用 PostgreSQL 12.9
。
似乎在升级后某些词成为 H2
数据库中的关键字,例如:day
、value
。调用集成测试后 Hibernate
在 DDL
部分失败。
这种情况的最佳解决方案是什么?
- 查看所有实体并在保留列名称周围应用反引号:
@NotNull
@Column(name = "day", nullable = false)
private LocalDate day;
@NotNull
@Column(name = "`day`", nullable = false)
private LocalDate day;
- 提供专用
SpringPhysicalNamingStrategy
并重写toPhysicalColumnName
方法仅用于集成测试目的。检查H2
数据库中的保留关键字列表并引用它们。
# Datasource related properties
spring.datasource.driver-class-name=org.h2.Driver
spring.datasource.url=jdbc:h2:mem:db;DB_CLOSE_DELAY=-1
spring.datasource.username=sa
spring.datasource.password=sa
spring.sql.init.mode=always
spring.sql.init.continue-on-error=true
spring.sql.init.platform=h2
spring.jpa.show-sql=true
spring.jpa.generate-ddl=true
spring.jpa.hibernate.ddl-auto=update
spring.jpa.properties.hibernate.jdbc.time_zone=UTC
spring.jpa.hibernate.naming.physical-strategy=[project-related-package-name-here].strategy.CustomH2NamingStrategy
spring.jpa.defer-datasource-initialization=true
我认为第一个解决方案应该适用于 PostgreSQL
和 H2
数据库。尽管 day
标识符在 PostgreSQL 12.9
中未保留,但可能会出现在未来的版本中。
第二个应该解决 H2
数据库的问题。
你怎么看?对于这种情况,也许有更好的解决方案?或者从 SQL:2016
标准中获取保留关键字列表,并通过自定义 SpringPhysicalNamingStrategy
?
在 H2 2.0 中,您可以通过将 ;NON_KEYWORDS=DAY,VALUE
附加到 JDBC URL 来使用 SET NON_KEYWORDS 设置,但正常的解决方案是在生成的 [=25] 中引用所有标识符=] 无条件地使用 spring.jpa.properties.hibernate.globally_quoted_identifiers=true
,例如。
当您尝试使用 H2 而不是 PostgreSQL 时,您通常还应该在 H2 的 JDBC URL 中包含 ;MODE=PostgreSQL;DATABASE_TO_LOWER=TRUE;DEFAULT_NULL_ORDERING=HIGH
。但是使用不同的 DBMS 进行生产和测试是个坏主意而且 Hibernate ORM 还不完全支持 H2 2.0。已编辑:Hibernate ORM 5.6.5.Final 具有对 H2 2.*.* 的基本支持,并且在较新版本中修复了一些其他问题。