我有一个布尔类型的 H2 列,但 Hibernate 使用
1
/0
而不是 TRUE
/FALSE
值来查询它,这会导致 Values of types "BOOLEAN" and "INTEGER" are not comparable
语法错误。
例如,Hibernate 5 会这样写
WHERE myBooleanColumn = 1
而不是
WHERE myBooleanColumn = TRUE
如何解决这个问题?
我的H2数据库版本是2.0.206,我使用的是Spring Boot 2.5.6。
您可以创建一个类来重写 Hibenate 的
Dialect
toBooleanValueString
方法 :
package com.myCorp;
import org.hibernate.dialect.H2Dialect;
public class H2DialectExtended extends H2Dialect {
@Override
public String toBooleanValueString(boolean bool) {
return bool ? "TRUE" : "FALSE";
}
}
并将其加载到 Spring Boot 测试中
application-test.properties
:
spring.jpa.properties.hibernate.dialect=com.myCorp.H2DialectExtended
这样,Hibernate 就会写:
WHERE myBooleanColumn = TRUE
而不是
WHERE myBooleanColumn = 1
这将解决问题,因为 myBooleanColumn 是 H2 布尔类型。
这对我有用(如果您使用的是 Oracle 模式):
@TestConfiguration
public class H2WithOracleModeTestConfiguration {
@Bean
public DataSource h2DataSource() {
EmbeddedDatabase embeddedDatabase = new EmbeddedDatabaseBuilder()
.setType(EmbeddedDatabaseType.H2)
.setName(UUID.randomUUID() + ";Mode=Oracle;DEFAULT_NULL_ORDERING=HIGH")
.build();
Mode mode = Mode.getInstance("ORACLE");
mode.limit = true;
// Here is the trick
mode.numericWithBooleanComparison = true;
return embeddedDatabase;
}
}
我正在使用 Spring Boot 2.7.X 和 H2 2.1.214。
如果类型匹配出错,可以使用MODE=....在
spring.datasource.url=jdbc:h2:mem:test;MODE=MySQL
中指定
但由于某种原因,当我指定 MODE=PostgreSQL 时,它并没有解决我的问题。
然后我明确指定了 hibernate 的方言:
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect
类型匹配的错误消失了。
我知道这是一个老问题,但我遇到了同样的问题并以不同的方式解决了它,所以如果将来有人遇到这个问题,我在这里陈述我的解决方案。
它是基于Bohemian的评论(我试图引用你,但我找不到方法,抱歉。
他建议更改 JDBC 字符串中的连接模式。我的连接字符串是:
spring.datasource.url: jdbc:h2:mem:testdb;NON_KEYWORDS=USER;
(我有一个表“user”,所以我需要禁用 H2 对“user”的关键字检查)。
我必须专门添加数据库模式“
MODE=MySQL
”才能使其与我的布尔字段一起使用。
这产生了最终的连接字符串:
spring.datasource.url: jdbc:h2:mem:testdb;NON_KEYWORDS=USER;MODE=MySQL
我在使用 h2 的单元测试中使用了它并且它有效
@BeforeAll
static void setUp() {
org.h2.engine.Mode mode = org.h2.engine.Mode.getInstance("ORACLE");
mode.limit = true;
mode.numericWithBooleKanComparison = true; //This fixes the issue
}
配置这些属性:
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
或者如果你使用yaml:
spring:
datasource:
url: jdbc:h2:mem:mydb
username: sa
password: password
driverClassName: org.h2.Driver
jpa:
spring.jpa.database-platform: org.hibernate.dialect.H2Dialect
考虑升级到最新版本的 spring-boot(当前为 2.6.2)。