Hibernate + Derby:不支持“BOOLEAN”和“INTEGER”之间的比较

我在查询Derby数据库时遇到问题。 我正在使用Hibernate和JPA。 问题与布尔列有关(可能)。 每个查询都以错误结束:

org.hibernate.exception.SQLGrammarException:不支持“BOOLEAN”和“INTEGER”之间的比较。 类型必须具有可比性。 字符串类型还必须具有匹配的排序规则。 如果排序规则不匹配,可能的解决方案是转换操作数以强制它们进行默认排序规则(例如SELECT tablename FROM sys.systables WHERE CAST(tablename AS VARCHAR(128))=’T1’)

您可以在下面找到示例代码和配置。 简化了样本以便于阅读。 这是我的JPA实体:

@Entity public abstract class Task implements Serializable { @Id @GeneratedValue(strategy = GenerationType.TABLE) protected long id; @Column protected boolean deleted; public long getId() { return id; } public boolean isDeleted() { return deleted; } public void setId(long id) { this.id = id; } public void setDeleted(boolean deleted) { this.deleted = deleted; } @Override public int hashCode() { return id; } @Override public boolean equals(Object object) { if (object == null) { return false; } if (!this.getClass().equals(object.getClass())) { return false; } EntityObject other = (EntityObject) object; if (this.id != other.id) { return false; } return true; } @Override public String toString() { return "EntityObject[ id=" + id + " ]"; } } 

我的JPA查询:

 SELECT t FROM Task t WHERE deleted = false 

我的JPA配置:

  org.hibernate.ejb.HibernatePersistence jdbc/myapp false      

哪里不对? 如何解决? 谢谢你的任何建议。

在Derby 10.7中添加了布尔数据类型,您似乎使用10.7或更新版本,因此您应该使用添加布尔支持的org.hibernate.dialect.DerbyTenSevenDialect方言。

您必须将布尔值设置为参数:

 String queryString = "SELECT t FROM Task t WHERE t.deleted = :trueValue"; Query query = entityManager.createQuery(queryString); query.setParameter("trueValue", true); query.getResultList(); 

希望它对你有用;)

使用Rafal的方法,但也必须添加

 @Override public String toBooleanValueString(boolean bool) { return bool ? "1" : "0"; } 

在我的方言中。 否则它在Hibernate 4.2.8下不起作用。

此外,我无法在persistence.xml中明确指定我的方言,因为我的应用程序针对Oracle和Derby运行。 所以我为我的方言添加了一个方言解析器:

  

解析器本身:

 public class DerbyBoolAsIntDialectResolver extends AbstractDialectResolver { @Override protected Dialect resolveDialectInternal(DatabaseMetaData metaData) throws SQLException { String databaseName = metaData.getDatabaseProductName(); int databaseMajorVersion = metaData.getDatabaseMajorVersion(); if ( "Apache Derby".equals( databaseName ) ) { final int databaseMinorVersion = metaData.getDatabaseMinorVersion(); if ( databaseMajorVersion > 10 || ( databaseMajorVersion == 10 && databaseMinorVersion >= 7 ) ) { return new DerbyBoolAsIntDialect(); } } return null; } } 

降级没有帮助。 这是适用于我的有效解决方案:

 import java.sql.Types; import org.hibernate.dialect.DerbyTenSevenDialect; public class DerbyDialect extends DerbyTenSevenDialect { public DerbyDialect() { // fix Derby dialect boolean data type mapping error registerColumnType(Types.BOOLEAN, "INTEGER"); } } 

我想最好将方言中的’true’和’false’常量映射到Derby数据类型,但现在上面已经足够了。