休眠计数集合大小而不初始化
有没有办法在不初始化的情况下计算关联集合的大小?
例如:
Select count(p.children) from Parent p
(有一个很好的理由,为什么我不能以任何其他方式做到这一点,因为我的where子句更复杂,而我的from子句是一个多态查询)
谢谢。
有没有办法在不初始化的情况下计算关联集合的大小?
例如:
Select count(p.children) from Parent p
(有一个很好的理由,为什么我不能以任何其他方式做到这一点,因为我的where子句更复杂,而我的from子句是一个多态查询)
谢谢。
除查询之外,其他可能的解决方案可能是映射(以 XML 表示法)。这样,您可以使用所需的任何查询获取 Parent,然后在不加载整个集合的情况下进行调用(仅执行类型查询)。children
lazy="extra"
parent.getChildren().size()
SELECT COUNT
带有注释,它将是
@OneToMany
@org.hibernate.annotations.LazyCollection(
org.hibernate.annotations.LazyCollectionOption.EXTRA
)
private Set<Child> children = new HashSet<Child>();
更新:引用自 Java Persistence with Hibernate, ch. 13.1.3:
如果调用任何不是标识符 getter 方法的方法,则将初始化代理;如果开始循环访问其元素或调用任何集合管理操作(如 and ),则会初始化集合。休眠提供了一个额外的设置,该设置对大型集合非常有用。它们可以被映射为额外的懒惰。[...]
size()
contains()
[如上所述映射,] 如果调用 、 或 — 查询数据库以检索必要的信息,则集合将不再初始化。如果是 a 或 a,则操作并直接查询数据库。
size()
contains()
isEmpty()
Map
List
containsKey()
get()
因此,使用如上所述映射的实体,您可以执行
Parent p = // execute query to load desired parent
// due to lazy loading, at this point p.children is a proxy object
int count = p.getChildren().size(); // the collection is not loaded, only its size
您可以使用 Session#createFilter,它是一种显式操作集合的 HQL 形式。例如,您提到了父母和孩子,因此如果您有一个人p,则最基本的形式是:
session.createFilter( p.getChildren(), "" ).list()
这只会返回一个子项列表。重要的是要注意,返回的集合不是“实时的”,它与p没有任何关联。
有趣的部分来自第二个论点。这是一个 HQL 片段。例如,在这里,您可能需要:
session.createFilter( p.getChildren(), "select count(*)" ).uniqueResult();
您提到您有一个 where 子句,因此您可能还需要:
session.createFilter( p.getChildren(), "select count(*) where this.age > 18" ).uniqueResult();
请注意,没有 from 子句。也就是说,from 子句是从关联中隐含的。集合的元素被赋予别名“this”,因此您可以从HQL片段的其他部分引用它。