如何在Hibernate中执行非多态HQL查询?

时间:2010-01-19 11:20:57

标签: java hibernate orm

我正在使用Hibernate 3.1.1,特别是我正在使用HQL查询。

根据documentation,Hibernate的查询是多态的:

  

from Cat as cat这样的查询不仅返回Cat的实例,还返回DomesticCat等子类的实例。

如何查询Cat的实例,而不查询其任何子类的实例?

我希望能够在不必明确提及每个子类的情况下完成它。

我知道以下选项,但发现它们并不令人满意:

  1. 在查询后手动过滤实例,或者:
  2. 在鉴别器列上手动添加WHERE子句。
  3. 让Hibernate允许用户决定查询是否应该是多态的,这是有意义的,但我找不到这样的选项。

    提前致谢!

5 个答案:

答案 0 :(得分:25)

class mapping中使用polymorphism="explicit"。这将导致查询仅返回指定类的实例而不返回其子类。

  

隐含多态意味着   班级的实例将是   由任何命名的查询返回   超类或实现的接口或   类,以及任何实例   将返回该类的子类   通过命名该类的查询   本身。显式多态意味着   将返回该类实例   仅通过明确命名的查询   那个班。

答案 1 :(得分:15)

SELECT cat FROM Cat cat WHERE cat.class='cat'

其中值'cat'Cat类的鉴别值。

如果您使用TABLE_PER_CLASS,请尝试cat.class='Cat')(班级名称)

这不是完全在discriminator列上的where子句,因为这样的查询将失败(鉴别器列仅在本机查询中可用)。

答案 2 :(得分:11)

JPA 2(Hibernate 3.5)增加了对非多态查询的支持,这与Hibernates .class属性非常相似(如上面的Bozho所述),但它不是特定于Hibernate的。这是使用TYPE运算符完成的。如在

Select b from Book b where TYPE(b) = Book

您可以在我的博客中详细了解here

的Eyal

答案 3 :(得分:1)

ORM模仿Java模型:如果一个对象是另一个类型的实例(如果PersianCat的实例也是Cat的一个实例),对Cat的任何查询都必须是多态的(想象一下你查询一个List并询问如果条目与instanceof Cat匹配。

即使是Bozho的解决方案也有点不纯,因为“类”列对于你的hibernate映射是不透明的,尽管我承认它是一个非常好的折衷方案。你可以通过classe的简单名称来获得鉴别器。

如果你很舒服并且正在使用每个类的表,你可以随时对Cat表进行本机查询以获取ID,然后通过hibernate获取条目

答案 4 :(得分:0)

查看BaseQueryReturnFieldsCalculatorGC;它动态地为'where'添加一个条件,它只选择class = XXX;您可以将此逻辑复制到HQLQueryTemplate并让用户定义'isNonPolymorphic'。

请注意,它只适用于每个层次的表,只有那时隐式类列才存在且可以选择。