【问题标题】:Duplicate records with hibernate joins and pagination具有休眠连接和分页的重复记录
【发布时间】:2017-03-20 17:33:43
【问题描述】:

我使用的是 hibernate 3.6.3 最终版本(我知道它已经很老了,但在我目前正在处理的这个项目中,现在就是这样)。
我在进行连接和分页时遇到问题,以便我在结果中复制一条记录,这是由休眠引起的。
这是我的代码:

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;
}

当我点击生成的查询并在数据库服务器上运行它时,我没有这个重复记录。但是调试我的代码,listCriteria.list() 返回带有重复的数据集。另外,当我注释掉这两行listCriteria.setFirstResult(params.getFirstResultIdx()); listCriteria.setMaxResults(params.getPageSize());,那么listCriteria.list() 没有重复,就可以了。
因此,这向我表明,分页和我所拥有的其他标准(连接和排序)存在一些问题。
有人知道如何解决这个问题吗?这是休眠错误吗?将休眠版本增加到最新(5.2.9.Final)有帮助吗?这么大的版本升级有什么潜在的问题吗?
感谢您提供任何帮助。

错别字

【问题讨论】:

    标签: java oracle hibernate


    【解决方案1】:

    两件事:

    • 如果您在同一页面中看到重复的行,则说明您的连接存在问题。尝试记录 SQL 查询,然后手动执行。解决此问题的最佳方法是使用criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
    • 对于您的分页,如果getOrdering() 为空,则不要添加任何order by。虽然,要正确分页,您绝对需要一个 order by 子句。将 listCriteria.addOrder(Order.asc("id")); 添加到您的代码中,以便 Id 是最后的排序方式。

    【讨论】:

    • 重复的行在不同的页面上。我尝试手动执行 SQL 查询,结果中没有重复记录。在这种情况下也给出了订购。你认为这是休眠错误吗?
    • 谢谢!毕竟问题在于订购。不是说它丢失了,而是它是模棱两可的。我按创建日期排序,这是 oracle 日期数据类型,db 中的数据具有相同的创建日期值。所以订购不是明确的。在通过 id 添加排序后(连同创建日期)一切正常。再次感谢您!
    • 有类似的查询界面。 @Guillaume 添加 DISTINCT_ROOT_ENTITY 并确保订单明确的解决方案不会导致任何欺骗。但是我看到了简短的分页结果;例如,要求 20 个项目,只得到 19 个。我相信 SQL 限制发送为 20,然后转换器挤出 1 个重复项,产生 19 个唯一行/对象。这里有解决方法吗?
    • @chrisinmtown ;是的,您必须确保您的查询不返回多个根元素。 oneToMany join fetch 实体会发生这种情况。如果有帮助,您可以尝试惰性连接。
    • 谢谢。在stackoverflow.com/questions/11038234/… 中讨论的所有 *-to-many 字段上将 FETCH_MODE 设置为 SELECT 后按预期工作
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-15
    • 2011-06-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-05
    相关资源
    最近更新 更多