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数据类型,但现在上面已经足够了。