Hibernate Criteria n + 1问题与maxresults [英] Hibernate Criteria n+1 issue with maxresults

查看:153
本文介绍了Hibernate Criteria n + 1问题与maxresults的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用hibernate ctiteria我想选择一个对象,并且它关联了一对多对象列表。我想通过这个列表进行分页,避免可怕的hibernate n + 1选择问题。



这是一个工作解决方案,需要11次访问10个父对象的数据库。

  Criteria criteria = this.getSession()。createCriteria(Mother.class); 
criteria.addOrder(Order.asc(title))
.setMaxResults(details.getMaxRows())
.setFirstResult(details.getStartResult())
.setFetchMode 小猫,FetchMode.SELECT);
List test = criteria.list();

这个解决方案只执行一个sql语句(hurray),但无法处理分页,即setMaxResults和setFirstResult在父对象上不正确Mother(boo)

  Criteria criteria = this.getSession()。createCriteria(Mother.class) ; 
criteria.addOrder(Order.asc(title))
.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY)
.setMaxResults(details.getMaxRows())
.setFirstResult(details。 getStartResult())
.setFetchMode(kittens,FetchMode.JOIN);
List test = criteria.list();

这似乎是这样一个常见的要求,但我已经找到了一个解决方案,没有运气。 / p>

任何接受者?

解决方案

(即我不知道一个便携式解决方案),但将其归结为2个查询(不论n)是非常简单的:

  Criteria criteria = this.getSession()。createCriteria(Mother.class); 
criteria.addOrder(Order.asc(title))
.setMaxResults(details.getMaxRows())
.setFirstResult(details.getStartResult())
.setProjection( Projections.id());
列表<?> ids = criteria.list();

criteria = getSession()。createCriteria(Mother.class)
.add(Restrictions.in(id,ids))
.setFetchMode(children,FetchMode .JOIN)
.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY)

return criteria.list();

对于某些数据库,子选取 children 可能工作也是如此。


Using hibernate ctiteria I want to select an object and it's associated oneToMany list of objects. I want to paginate through this list avoiding the dreaded hibernate n+1 select issue

Here's a working solution which requires 11 trips to the database for 10 parent objects.

Criteria criteria = this.getSession().createCriteria(Mother.class);
criteria.addOrder(Order.asc("title"))
.setMaxResults(details.getMaxRows())
.setFirstResult(details.getStartResult())
.setFetchMode("kittens", FetchMode.SELECT);
List test = criteria.list();

And here's a solution which executes only one sql statement (hurray) but cannot handle pagination ie the setMaxResults and setFirstResult are incorrect on the parent object Mother (boo)

Criteria criteria = this.getSession().createCriteria(Mother.class);
criteria.addOrder(Order.asc("title"))
.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY)
.setMaxResults(details.getMaxRows())
.setFirstResult(details.getStartResult())
.setFetchMode("kittens", FetchMode.JOIN);
List test = criteria.list();

This seems like such a common requirement but I've dug around for a solution with no luck.

Any takers?

解决方案

Getting it down to 1 query is tough (i.e. I don't know a portable solution), but getting it down to 2 queries (irrespective of n) is pretty simple:

Criteria criteria = this.getSession().createCriteria(Mother.class);
criteria.addOrder(Order.asc("title"))
    .setMaxResults(details.getMaxRows())
    .setFirstResult(details.getStartResult())
    .setProjection(Projections.id());
List<?> ids = criteria.list();

criteria = getSession().createCriteria(Mother.class)
    .add(Restrictions.in("id", ids))
    .setFetchMode("children", FetchMode.JOIN)
    .setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY)

return criteria.list();

For some databases, subselect fetching children might work, too.

这篇关于Hibernate Criteria n + 1问题与maxresults的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆