Hibernate @Where 子句在 HSQL 和 MySQL 之间不一致

Posted

技术标签:

【中文标题】Hibernate @Where 子句在 HSQL 和 MySQL 之间不一致【英文标题】:Hibernate @Where clause inconsistent between HSQL and MySQL 【发布时间】:2014-11-07 11:49:52 【问题描述】:

mysql 中使用休眠和测试我使用 HSQL。 在许多集合中,我们使用基于 @Where 子句的过滤。例如:

@Column(name="CONDITIONS")
@OneToMany(cascade=CascadeType.ALL)
@JoinColumn(name="CATEGORIES_PKEY")
@Cascade(org.hibernate.annotations.CascadeType.DELETE)
@Where(clause="deleted_flag = 'false'")
public List<CategoryConditionMapping> getMappedConditions() 
    return mappedConditions;

MySQL中,

这行得通:

@Where(clause="deleted_flag = 'false'")

这不起作用:

@Where(clause="deleted_flag = FALSE")

HSQL中,

这行得通:

@Where(clause="deleted_flag = FALSE")

这不起作用:

@Where(clause="deleted_flag = 'false'")

Hsql 开始支持@Where(clause="deleted_flag = FALSE"),只有在添加自定义HSQLDialect 之后:

public class CustomHSQLDialect extends HSQLDialect 

public CustomHSQLDialect() 
    super();
    registerKeyword("true");
    registerKeyword("false");
    registerKeyword("unknown");


尝试为该方言注册更多关键字。例如

    registerKeyword("'false'");
    registerKeyword("'true'");

但它没有任何作用。 HSQL 抛出异常,同时尝试使用 @Where(clause="deleted_flag = 'false'")

原因:org.hsqldb.HsqlException:数据异常:强制转换的字符值无效 在 org.hsqldb.error.Error.error(未知来源) 在 org.hsqldb.error.Error.error(未知来源) 在 org.hsqldb.Scanner.convertToBit(未知来源) 在 org.hsqldb.types.BitType.castOrConvertToType(未知来源) 在 org.hsqldb.types.BitType.castToType(未知来源) 在 org.hsqldb.ExpressionOp.getCastExpression(未知来源) 在 org.hsqldb.ExpressionLogical.resolveTypesForComparison(未知来源) 在 org.hsqldb.ExpressionLogical.resolveTypes(未知来源) 在 org.hsqldb.ExpressionLogical.resolveTypes(未知来源) 在 org.hsqldb.QuerySpecification.resolveExpressionTypes(未知来源) 在 org.hsqldb.QuerySpecification.resolveTypesPartOne(未知来源) 在 org.hsqldb.QueryExpression.resolve(未知来源) 在 org.hsqldb.ParserDQL.compileCursorSpecification(未知来源) 在 org.hsqldb.ParserCommand.compilePart(未知来源) 在 org.hsqldb.ParserCommand.compileStatement(未知来源) 在 org.hsqldb.Session.compileStatement(未知来源) 在 org.hsqldb.StatementManager.compile(未知来源) 在 org.hsqldb.Session.execute(未知来源)

HSQL 试图将字符串转换为布尔值并失败。

我们如何让 HSQL 稍微理解字符串 'false' 或者我们如何让 @Where 子句泛型以在 HSQL 和 MySQL 上愉快地工作

【问题讨论】:

这个注解所指的实际属性是什么?它是布尔类型的吗? 它在集合(OneToMany)上被注释,但 deleteg_flag 是一个布尔值 - 它在 where 子句中被评估 那么正确的形式应该是deleted_flag = false。数据库是如何创建的?它是在这两种情况下自动生成的,还是仅在使用 HSQL 时自动生成?它可能会帮助您使用例如 Log4JDBC 来查看具体生成的 SQL。 【参考方案1】:

也许您没有为该列使用正确的类型。在 MySQL 中使用布尔值的最佳方式是使用 BIT 或 TINYINT,在 Entity 类中您将其定义为“布尔值”。如果它不起作用,您甚至应该像这样添加@Type:

@Column(name="DELETED_FLAG")
@Type(type = "org.hibernate.type.NumericBooleanType")
public boolean deleted_flag = true;

然后hibernate会知道如何处理这个属性。查看这篇文章以了解 mysql 数据类型: http://dev.mysql.com/doc/connector-j/en/connector-j-reference-type-conversions.html

【讨论】:

感谢您的宝贵时间,不,事实并非如此。对于我的问题的另一个评论。,我已经回答了。现在我用更多细节更新了我的问题

以上是关于Hibernate @Where 子句在 HSQL 和 MySQL 之间不一致的主要内容,如果未能解决你的问题,请参考以下文章

Spring JPA Hibernate JPQL 查找在 where 子句中传递的项目的索引

如何使用 Hibernate 为 Spring data JPA 的所有查找方法添加全局 where 子句?

如何使用 IN 修复 Hibernate Named Native Query 的 Where 子句

Hibernate在超类中定义@Where注解

JPA,Hibernate和Spring Data:在MS SQL服务器上的where子句中将字符串转换为数字

在 HSQL 左外连接子句中使用 SUBSTR