【问题标题】:How to solve H2 database `Values of types "BOOLEAN" and "INTEGER" are not comparable` syntax error?如何解决 H2 数据库`“BOOLEAN”和“INTEGER”类型的值不可比较`语法错误?
【发布时间】:2022-07-30 02:33:50
【问题描述】:

我有一个布尔类型的 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。

【问题讨论】:

  • 我从来没有做过这样的事情。你的配置中有什么方言?与其破解方言,不如试试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
  • 嗨@Bohemian,当一列被定义为布尔值但Hibernate提供1/0值而不是真/假时,就会出现问题。 ,无论出于何种原因,H2 support group 上也报告了此问题。谢谢。
  • 如果 H2 模式设置为 MySQL,则将 1/0 等同于 true/false 将是正确的行为。尝试将;MODE=PostgreSQL(或任何您的数据库-many are supported)添加到您的jdbc 连接url,即jdbc:h2:...;MODE=PostgreSQL。顺便说一句,你的 jdbc url 是是什么?
  • 真正的数据库是Oracle。数据源以编程方式初始化,因为我需要mode.limit=true hack 才能在LIMIT 子句上不出现语法错误:@Bean @Profile("test") public DataSource dataSource() { // Ref groups.google.com/g/h2-database/c/yxnv64Ak-u8/m/n-kqYV_yBQAJ org.h2.engine .Mode mode = org.h2.engine.Mode.getInstance("ORACLE"); mode.limit = true; DriverManagerDataSource dataSource = new DriverManagerDataSource(); dataSource.setDriverClassName("org.h2.Driver"); dataSource.setUrl("jdbc:h2:mem:vessaging;DB_CLOSE_DELAY=-1");
  • 令人惊讶的是,恕我直言,Oracle 没有布尔数据类型。传统上,使用char 并存储Y 和N 值,但也经常使用存储1 和0 的numeric。听起来H2后来选择了那个。您的“布尔”列是什么数据类型?

标签: hibernate h2


【解决方案1】:

您可以创建一个覆盖 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 布尔类型。

【讨论】:

  • 这对我有用。春季启动 2.7.1。奇怪的是,当他们在 Spring Boot 2.7.0 中将 H2 的版本升级到 2.x 时,我不得不这样做。
【解决方案2】:

我知道这是一个老问题,但我遇到了同样的问题并以不同的方式解决了它,所以如果将来有人遇到这个问题,我会在这里陈述我的解决方案。

这是基于 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

【讨论】:

    【解决方案3】:

    配置这些属性:

    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
    

    考虑升级到latest version of spring-boot(当前为 2.6.2)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-04-24
      • 1970-01-01
      • 2021-05-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-16
      • 1970-01-01
      相关资源
      最近更新 更多