Java 使用hibernate联接和分页复制记录

Java 使用hibernate联接和分页复制记录,java,oracle,hibernate,Java,Oracle,Hibernate,我使用的是hibernate 3.6.3最终版本(我知道它很旧,但目前我正在进行的项目就是这样)。 为了在结果中复制一条记录,我在执行联接和分页时遇到问题,这是由hibernate引起的。 这是我的代码: public Page<T> findByCriteriaPaginated(PageParams params, Criteria countCriteria, Criteria listCriteria, String[] joins) { Page<T>

我使用的是hibernate 3.6.3最终版本(我知道它很旧,但目前我正在进行的项目就是这样)。
为了在结果中复制一条记录,我在执行联接和分页时遇到问题,这是由hibernate引起的。
这是我的代码:

public Page<T> findByCriteriaPaginated(PageParams params, Criteria countCriteria, Criteria listCriteria, String[] joins) {
    Page<T> page = new Page<T>(params);
    // count criteria
    countCriteria.setProjection(Projections.rowCount());
    page.setTotalCount(((Long) countCriteria.uniqueResult()).intValue());
    // fetch criteria
    listCriteria.setFirstResult(params.getFirstResultIdx());
    listCriteria.setMaxResults(params.getPageSize());
    if (params.getOrdering() != null && params.getOrdering().getSize() > 0) {
        for (Iterator<String> it = params.getOrdering().getKeyIterator(); it.hasNext();) {
            String key = it.next();
            if (params.getOrdering().isAscending(key)) {
                listCriteria.addOrder(Order.asc(key));
            } else {
                listCriteria.addOrder(Order.desc(key));
            }
        }
    }
    if (joins != null && joins.length > 0) {
        for (String s : joins) {
            listCriteria.setFetchMode(s, FetchMode.JOIN);
        }
    }
    page.setResults(listCriteria.list());
    return page;
}
公共页面findByCriteriaPaginated(PageParams参数、Criteria countCriteria、Criteria listCriteria、String[]联接){
第页=新页(参数);
//计数标准
countCriteria.setProjection(Projections.rowCount());
page.setTotalCount(((长)countCriteria.uniqueResult()).intValue());
//获取条件
setFirstResult(params.getFirstResultId());
setMaxResults(params.getPageSize());
if(params.getOrdering()!=null&¶ms.getOrdering().getSize()>0){
for(Iterator it=params.getOrdering().getKeyIterator();it.hasNext();){
String key=it.next();
if(params.getOrdering().isAscending(键)){
listCriteria.addOrder(Order.asc(key));
}否则{
listCriteria.addOrder(Order.desc(key));
}
}
}
if(joins!=null&&joins.length>0){
用于(字符串s:连接){
setFetchMode(s,FetchMode.JOIN);
}
}
page.setResults(listCriteria.list());
返回页面;
}
当我点击生成的查询并在DB服务器上运行它时,我没有这个重复的记录。但在调试我的代码时,
listCriteria.list()
返回重复的数据集。另外,当我注释掉这两行时,
listCriteria.setFirstResult(params.getFirstResultId());
setMaxResults(params.getPageSize())
,然后
listCriteria.list()
没有重复项,可以。
因此,这向我表明分页和其他条件(连接和排序)存在一些问题。
有人知道如何解决这个问题吗?这是冬眠虫吗?将hibernate版本增加到最新版本(5.2.9.Final)会有帮助吗?如此大规模的版本升级是否存在任何潜在问题?
谢谢你的帮助

不匹配有两件事:

  • 如果在同一页中看到重复的行,则表示联接存在问题。尝试记录SQL查询,然后手动执行它。解决此问题的最佳方法是使用
    criteria.setResultTransformer(criteria.DISTINCT\u ROOT\u ENTITY)
  • 对于分页,如果
    getOrdering()
    为空,则不添加任何
    orderby
    。尽管如此,要正确分页,您绝对需要一个ORDERBY子句。添加
    listCriteria.addOrder(Order.asc(“id”)添加到您的代码中,因此Id是最后的订购方法

重复的行位于不同的页面上。我尝试手动执行SQL查询,结果中没有重复记录。在这种情况下也给出了排序。你认为这是冬眠虫吗?谢谢!毕竟,问题在于订购。并不是说它不见了,而是模棱两可。我按创建日期排序,这是oracle日期数据类型,数据库中的数据具有相同的创建日期值。因此,订购并不是毫不含糊的。添加按id排序(以及创建日期)后,一切正常。再次感谢你!具有类似的查询界面@Guillaume的解决方案是添加不同的_根_实体并确保无歧义的顺序,因此不会产生重复。但我看到了简短的分页结果;e、 例如,要20件,只得到19件。我相信SQL限制发送为20,然后transformer挤出1个重复,产生19个唯一的行/对象。这里有解决办法吗?@chrisinmtown;是的,您必须确保查询不会返回多个根元素。这发生在
oneToMany join-fetch
实体中。如果有帮助的话,你可以试试懒加入。谢谢。在我将FETCH_MODE设置为在所有*到多个字段上选择后,将按预期工作,如中所述