Hibernate - 具有分页的独特结果

Ash*_*ish 6 java sql hibernate

多年来这似乎是一个众所周知的问题,可以在这里阅读:http: //blog.xebia.com/2008/12/11/sorting-and-pagination-with-hibernate-criteria-how-it-can-走,错用,加入/

甚至在hibernate faqs中找到引用:

https://community.jboss.org/wiki/HibernateFAQ-AdvancedProblems#Hibernate_does_not_return_distinct_results_for_a_query_with_outer_join_fetching_enabled_for_a_collection_even_if_I_use_the_distinct_keyword

这也已在之前的SO上讨论过

如何通过连接和基于行的限制(分页)在hibernate中获得明显的结果?

问题是,即使经过所有这些资源,我也无法解决我的问题,这似乎与这个标准问题有点不同,尽管我不确定.

这里提出的标准解决方案涉及创建两个查询,第一个用于获取不同的ID,然后在更高级别的查询中使用这些查询来获得所需的分页.我的情况下的hibernate类就像

A
 - aId
 - Set<B>

B
 - bId 
Run Code Online (Sandbox Code Playgroud)

在我看来,子查询似乎对我来说很好,并且能够获得不同的aIds但是应该进行分页的外部查询再次获取重复项,因此子查询中的distinct不起作用.

假设我有一个A对象有一组四个B对象,我的分析是因为引入了set,​​同时获取了数据

session.createCriteria(A.class).list();
Run Code Online (Sandbox Code Playgroud)

hibernate在列表中填充指向一个对象的四个引用.因此,标准解决方案对我来说是失败的.

有人可以帮忙提出这个案例的解决方案吗?

编辑:我决定自己从独特的结果集中进行分页.另一个同样糟糕的方法可能是延迟加载B对象但是这需要对所有A对象进行单独查询以获取相应的B对象

szh*_*hem 6

考虑使用像这样的DistinctRootEntity结果转换器

session.createCriteria(A.class)
    .setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY).list();
Run Code Online (Sandbox Code Playgroud)

UPDATE

查询一对多关联的样本.

public Collection<Long> getIDsOfAs(int pageNumber, int pageSize) {
    Session session = getCurrentSession();

    Criteria criteria = session.createCriteria(A.class)
        .setProjection(Projections.id())
        .addOrder(Order.asc("id"));

    if(pageNumber >= 0 && pageSize > 0) {
        criteria.setMaxResults(pageSize);
        criteria.setFirstResult(pageNumber * pageSize);
    }

    @SuppressWarnings("unchecked")
    Collection<Long> ids = criteria.list();
    return ids;
}

public Collection<A> getAs(int pageNumber, int pageSize) {
    Collection<A> as = Collections.emptyList();

    Collection<Long> ids = getIDsOfAs(pageNumber, pageSize);
    if(!ids.isEmpty()) {
        Session session = getCurrentSession();

        Criteria criteria = session.createCriteria(A.class)
            .add(Restrictions.in("id", ids))
            .addOrder(Order.asc("id"))
            .setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
        @SuppressWarnings("unchecked")
        as = criteria.list(); 
    }    

    return as;
}
Run Code Online (Sandbox Code Playgroud)