【问题标题】:How entity comparison works in JPQL WHERE clause?JPQL WHERE 子句中的实体比较如何工作?
【发布时间】:2014-12-05 16:00:34
【问题描述】:

在 JPQL 中如何评估实体比较(相等)语句:是通过身份比较,还是通过 equals() 或其他方式?

我花了几个小时在谷歌上搜索并浏览了 Hibernate 和 JPA 的规范,但仍然找不到它是如何工作的。考虑以下实体:

class MyProductType{Integer id;}
class MyProduct{Integer id; MyProductType pType;}

现在是 JPQL/HQL 查询:

SELECT t FROM MyProductType t, MyProduct p WHERE p.pType = t

(我知道这是一个丑陋的查询,只关注 where 子句语义。)

那么p.pType = t 是如何评估的呢?

JSR 317 提到了“entity_expression”比较,但它的行为并未明确。

编辑:我不喜欢 Rika 下面的建议是 .id 方法包括隐式内部联接,如果查询使用外部(左)联接,这通常不是您想要的。

【问题讨论】:

  • 该查询有效吗?我问的原因是因为通常人们会看到 p.pType.id = t.id 或类似的东西。因为你还在从数据库中查询,而数据库本身不在对象中。
  • 这是一个简化的示例查询。我目前的实际情况要复杂得多。但是是的,它适用于实体比较。问题是它是如何工作的(JPA 是按照您的描述进行 id 比较还是在实体上使用 equals() )。我想弄清楚的是我是否可以依赖简短的语法,或者我必须按照您的建议执行完整的 ID 语句。

标签: hibernate jpa where


【解决方案1】:

我在http://www.objectdb.com/java/jpa/query/jpql/comparison 找到了这个,非常有趣,好问题。

用户定义类的实例(实体类和可嵌入 类)可以使用相等运算符(=、、==、 !=)。对于实体,如果 e1 和 e2 具有相同的类型并且 相同的主键值。对于可嵌入对象,如果 e1 和 e2,则 e1 = e2 内容完全相同。

所以它似乎检查对象的主键值和对象的类型。所以看起来p.pType = t,它会检查(假设id是主键)p.pType的id和t的id,看看它们是否相等。然后它将检查两个实体是否属于同一类型或 MyProductType。

【讨论】:

  • 我也发现了。但它适用于 ObjectDB 而不是一般的 JPA。感谢您的评论。在使用 Hibernate 进行一些调试后,我发现实体比较转换为与 JPQL 中的 .id 比较完全相同的 SQL。因此,如果几天后没有其他答案,我想我会将您的答案标记为已接受。
【解决方案2】:

我在带有 EclipseLink 和 MySQL DB 的 NetBeans 环境中做了同样的事情。生成的 SQL 语句使用外键(在引用另一个类的对象的类的表中)和被引用对象的主键值。

【讨论】:

    猜你喜欢
    • 2016-11-02
    • 2021-02-09
    • 1970-01-01
    • 1970-01-01
    • 2015-06-26
    • 1970-01-01
    • 1970-01-01
    • 2013-12-26
    • 1970-01-01
    相关资源
    最近更新 更多