我想在Hibernate中使用@Where注释来删除已被该对象上的布尔属性标记为“已删除”的对象.例如,以下内容应该可以防止Hibernate加载任何已删除的地址:
@OneToMany(mappedBy="contact") @Where(clause="deleted=FALSE") private Set<Address> addresses;
但是,当我使用像deleted = FALSE这样的子句时,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’时,我得到以下异常:
解决方法
我发现了关于这个的错误报告已经有六年多没有解决了!关于此问题,Hibernate问题跟踪器有
HHH-1587,HHH-2775和
ANN-647.
解决方案是创建一个自定义的Dialect类,它将true,false和unknown注册为关键字(这些是sql规范中的官方布尔文字).这会导致Hibernate将它们识别为关键字,从而停止为它们添加前缀,就像它们是列一样.
public class ImprovedHsqlDialect extends HsqlDialect { public ImprovedHsqlDialect() { super(); registerKeyword("true"); registerKeyword("false"); registerKeyword("unknown"); } }
一旦使用了这个方言,@ Where(clause =“deleted = FALSE”)就能正常工作.