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

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

根据文档 ,Hibernate的查询是多态的:

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

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

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

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

  1. 在查询后手动过滤实例,或者:
  2. 在discriminator列上手动添加WHERE子句。

Hibernate允许用户决定查询是否应该是多态的,这是有意义的,但我找不到这样的选项。

提前致谢!

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

隐式多态意味着类的实例将由命名任何超类或实现的接口或类的查询返回,并且类的任何子类的实例将由命名类本身的查询返回。 显式多态意味着只有显式命名该类的查询才会返回类实例。

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

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

如果您正在使用TABLE_PER_CLASS ,请尝试cat.class='Cat' )(类的名称)

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

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

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

您可以在我的博客中阅读更多相关信息

的Eyal

ORM模仿Java模型:如果对象是另一种类型的实例(如果PersianCat的实例也是Cat的实例),则对Cat的任何查询都必须是多态的(假设您查询List并询问条目匹配instanceof Cat

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

如果你很舒服并且 每个类都使用表,那么你总是可以对Cat表进行本机查询以获取id,然后通过hibernate获取条目。

看看BaseQueryReturnFieldsCalculatorGC; 它动态地向’where’添加条件,该条件仅选择class = XXX; 您可以将此逻辑复制到HQLQueryTemplate并让用户定义’isNonPolymorphic’。

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