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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2093025/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-29 19:24:08  来源:igfitidea点击:

How to perform a non-polymorphic HQL query in Hibernate?

javahibernateorm

提问by Eli Acherkan

I'm using Hibernate 3.1.1, and in particular, I'm using HQL queries.

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

According to the documentation, Hibernate's queries are polymorphic:

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

A query like: from Cat as catreturns instances not only of Cat, but also of subclasses like DomesticCat.

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

How can I query for instances of Cat, but not of any of its subclasses?

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

I'd like to be able to do it without having to explicitly mention each subclass.

我希望能够在不必明确提及每个子类的情况下做到这一点。

I'm aware of the following options, and don't find them satisfactory:

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

  1. Manually filtering the instances after the query, OR:
  2. Manually adding a WHERE clause on the discriminator column.
  1. 在查询后手动过滤实例,或者:
  2. 在鉴别器列上手动添加 WHERE 子句。

It would make sense for Hibernate to allow the user to decide whether a query should be polymorphic or not, but I can't find such an option.

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

Thanks in advance!

提前致谢!

采纳答案by Rob H

Use polymorphism="explicit"in the class mapping. This will cause queries to return only instances of the named class and not its subclasses.

使用polymorphism="explicit"类映射。这将导致查询仅返回命名类的实例,而不返回其子类。

Implicit polymorphism means that instances of the class will be returned by a query that names any superclass or implemented interface or class, and that instances of any subclass of the class will be returned by a query that names the class itself. Explicit polymorphism means that class instances will be returned only by queries that explicitly name that class.

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

回答by Bozho

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

where the value 'cat'is the discriminator value of the Catclass.

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

If you are using TABLE_PER_CLASS, then try cat.class='Cat') (the name of the class)

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

This is not exactlya where clause on the discriminator column, because such a query will fail (the discriminator column is available only in native queries).

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

回答by Eyal Lupu

JPA 2 (Hibernate 3.5) adds support for non-polymorphic queries, this is very similar to Hibernates .class property (as Bozho answered above) but it is not Hibernate specific. This is done using the TYPE operator. As in

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

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

You can read more about hereit in my blog

你可以在我的博客中阅读更多关于这里的信息

Eyal

艾尔

回答by Miguel Ping

The ORM mimics the Java Model: if an object is an instance of another type (if an instance of PersianCat is an instance of Cat also), any query on Cat will have to be polymorphic (imagine you querying a List and asking if the entries match instanceof Cat.

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

Even Bozho's solution is somewhat impure, since the 'class' column is supposedly opaque to your hibernate mapping, although I admit its a very good compromise. You can simply get the discriminator through the classe's simple name.

甚至 Bozho 的解决方案也有些不纯,因为 'class' 列据说对您的休眠映射是不透明的,尽管我承认这是一个很好的折衷方案。您可以通过类的简单名称简单地获取鉴别器。

If you're comfy andare using table per classyou can always do a native query to the Cat table to get the ids and then get the entries through hibernate.

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

回答by friendlyfire

Look at BaseQueryReturnFieldsCalculatorGC; it dynamically adds a condition to the 'where' which selects only where class=XXX; you can duplicate this logic to the HQLQueryTemplate and have the user define 'isNonPolymorphic'.

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

Note that it will only work with table-per-hierarchy, cos only then does the implicit class column exist and is selectable.

请注意,它仅适用于每个层次结构的表,因为只有隐式类列存在并且是可选的。