7

我想@Where在 Hibernate 中使用注释来删除已被该对象上的布尔属性标记为“已删除”的对象。例如,以下内容应防止 Hibernate 加载任何已删除的地址:

@OneToMany(mappedBy="contact")
@Where(clause="deleted=FALSE")
private Set<Address> addresses; 

但是,当我使用像deleted=FALSEthen 这样的子句时,Hibernate 会通过在布尔文字前面加上表名来破坏布尔文字,这会导致查询失败。例如:

select ... from address address0_ where  ( address0_.deleted=address0_.FALSE)  and address0_.contact_id=?

我所期望的是类似于(address0_.deleted=FALSE)而不是(address0_.deleted=address0_.FALSE).

有没有办法指定 @Where 子句或配置 Hibernate 以正确输出布尔值?


PS。请注意,某些数据库可以将布尔值指定为字符串文字,如下所示:

@Where(clause="deleted='FALSE'")

这将被转换为(address0_.deleted='FALSE')在例如 PostgreSQL 中运行良好的。但是我在这个项目中使用 HSQLDB,而 HSQLDB 似乎不支持布尔字符串文字。在 HSQL 上,使用时出现以下异常deleted='FALSE'

org.hsqldb.HsqlException: data exception: invalid character value for cast

4

2 回答 2

5

我发现了关于这个问题的错误报告,这些错误报告已经六年多没有解决了!Hibernate 问题跟踪器在该问题上有HHH-1587HHH-2775ANN-647

解决方案是创建一个自定义的方言类,它注册true,falseunknown作为关键字(这些是 SQL 规范中的官方布尔文字)。这会导致 Hibernate 将它们识别为关键字,从而停止为它们添加前缀,就好像它们是列一样。

这是我的自定义方言类,它为我解决了这个问题:

public class ImprovedHSQLDialect extends HSQLDialect {

    public ImprovedHSQLDialect() {
        super();
        registerKeyword("true");
        registerKeyword("false");
        registerKeyword("unknown");
    }
}

一旦使用此方言,就@Where(clause="deleted=FALSE")可以正常工作。

于 2012-05-24T05:07:08.157 回答
2

在表定义中将列创建为 BOOLEAN 时,最新的 HSQLDB 支持WHERE active = TRUE,WHERE active = 'TRUE'以及WHERE active.

Hibernate 可能正在创建一个 BIT 列,在这种情况下WHERE active = TRUEWHERE active = B'1'WHERE active = 1将起作用。

请为这些功能使用 2.2.8 或更高版本。

于 2012-05-24T10:00:36.830 回答