删除重复记录时导致错误的分页结果

时间:2015-07-27 19:29:55

标签: hibernate grails pagination criteria hibernate-criteria

我使用以下标准和分页参数。由于加入而生成了一些重复记录,因此我使用了setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY)。它删除了重复记录,但似乎在应用分页后删除了重复记录。

例如:如果offset是20,则max是10.这意味着它应该获取20-30条记录。但是假设记录28,29和30是重复的,因此它们被删除,在页面中只显示20-27条记录。所以第三页只显示20-27条记录,即使这些记录不是最后一条。

  return Question.createCriteria().list(offset: offset,max: max) {
        createAlias("questionHistory","qh")
        if(createdStartDate!=null){
            ge('createdDate',createdStartDate)
        }
        if(createdEndDate!=null){
            le('createdDate',createdEndDate)
        }
        if(folderId>0){
            eq('folder.id',folderId)
        }else if(itemBankId>0){
            or{
                folders.each {
                    eq('folder.id',it.id)
                }
            }
        }
      ....
      ......
       if(authorIds?.size()>0){
            'in'("qh.changedBy.id",authorIds)
        }
      ..........
      ..................
      ....................................
       setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY)
    }

我知道原因是因为首先执行标准然后删除重复记录。有没有办法获取等于找到的重复记录数的下一条记录(如果有的话)?

3 个答案:

答案 0 :(得分:1)

我已经解决了。我没有在list()中使用分页参数,而是使用了setFirstResult / setMaxResults。但缺点是它没有给出'totalCount'值,因此需要为它激发一个单独的查询。

解决方案:

setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
setFirstResult(offset)
setMaxResults(max)

首先删除重复,然后应用分页给出正确的结果。

答案 1 :(得分:0)

加入收藏品时难以实现分页;另一种方法是使用子查询,如here所述。

答案 2 :(得分:0)

我遗憾地从未设法做到这一点。当连接和分页混合在一起时,Hibernate会丢失,实际上我认为它必须是:AFAIK解决同一域类实例拥有多行问题的唯一方法是检查域类并查看它是否存在有一个主键,然后通过它聚合结果。我不确定这是否总是可行的。

在任何情况下,我“解决”这个问题的方法是创建一个单独的查询来评估条件,然后创建一个查询以应用分页(这可以触发另一个查询以进行结果计数)。

因此,使用描述失败案例的要点:https://gist.github.com/deigote/549dcecdbb2a6ba80074

我会通过以下方式解决:

def matchedIds = Car.createCriteria().list([:]) {
   distinct 'id'
   createAlias('brands', 'brands', CriteriaSpecification.INNER_JOIN)
   ... // criterias here
}

def actualResults = Car.createCriteria(max: maxResults, first: firstResults).list {
  'in'('id', matchedsIds)
}

actualResults包含当前的“页面”结果,并允许您调用totalCount来获取结果总数。

相关问题