我在查询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配置:
<persistence-unit name="PU1" transaction-type="JTA">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<jta-data-source>jdbc/myapp</jta-data-source>
<exclude-unlisted-classes>false</exclude-unlisted-classes>
<properties>
<property name="hibernate.hbm2ddl.auto" value="update"/>
<property name="hibernate.dialect" value="org.hibernate.dialect.DerbyDialect"/>
</properties>
</persistence-unit>
有什么问题?如何解决?感谢您的任何建议。
答案 0 :(得分:4)
在Derby 10.7中添加了布尔数据类型,您似乎使用了10.7或更新版本,因此您应该使用添加布尔支持的org.hibernate.dialect.DerbyTenSevenDialect
方言。
答案 1 :(得分:3)
您必须将布尔值设置为参数:
String queryString = "SELECT t FROM Task t WHERE t.deleted = :trueValue";
Query query = entityManager.createQuery(queryString);
query.setParameter("trueValue", true);
query.getResultList();
希望它对你有用;)
答案 2 :(得分:2)
使用Rafal的方法,但也必须添加
@Override
public String toBooleanValueString(boolean bool) {
return bool ? "1" : "0";
}
在我的方言中。否则它在Hibernate 4.2.8下无法正常工作。
此外,当我的应用程序针对Oracle和Derby运行时,我无法在persistence.xml中明确指定我的方言。所以我为我的方言添加了一个方言解析器:
<property name="hibernate.dialect_resolvers" value="...DerbyBoolAsIntDialectResolver"/>
解析器本身:
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;
}
}
答案 3 :(得分:0)
降级没有帮助。这是适用于我的有效解决方案:
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");
}
}
我想最好将dialect中的'true'和'false'常量映射到Derby数据类型,但现在上面已经足够了。