Hibernate Criteria n+1 issue with maxresults

梦想与她 提交于 2019-12-03 06:44:56

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.

As far as I know there are no good ways to solve this problem except for the following trick with native SQL query (exact SQL syntax depends on your DBMS):

List<Mother> result = s.createSQLQuery(
    "select {m.*}, {k.*} " +
    "from (select limit :firstResult :maxResults * from Mother m) m " +
    "left join Kitten k on k.motherId = m.id"
    )
    .addEntity("m", Mother.class)
    .addJoin("k", "m.kittens")
    .setParameter("firstResult", ...)
    .setParameter("maxResults", ...)
    .setResultTransformer(MyDistrictRootEntityResultTransformer.INSTANCE)
    .list();

...

// Unfortunately built-in DistrictRootEntityResultTransformer cannot be used
// here, since it assumes that root entity is the last in the tuple, whereas
// with addEntity()/addJoin() it's the first in the tuple
public class MyDistrictRootEntityResultTransformer implements ResultTransformer {
    public static final MyDistrictRootEntityResultTransformer INSTANCE = new MyDistrictRootEntityResultTransformer();

    public Object transformTuple(Object[] tuple, String[] aliases) {
        return tuple[0];
    }

    public List transformList(List collection) {
        return DistinctResultTransformer.INSTANCE.transformList(collection);
    }
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!