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

Wrong pagination result when removing duplicate records

我将以下标准与分页参数一起使用。由于加入而产生了一些重复的记录,所以我使用了 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)
    }

我知道是因为先执行了条件,然后删除了重复的记录。有什么方法可以获取等于找到的重复记录数的下一条记录(如果有的话)?

拼接集合时很难实现分页;另一种方法是使用子查询,如 here.

所述

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

解决方案:

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

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

遗憾的是,我从未成功完成这项工作。当连接和分页混合在一起时,Hibernate 丢失了,实际上我认为它一定是:AFAIK 解决同一域 class 实例有多行问题的唯一方法是检查域 class 看是否有主键,然后根据主键聚合结果。我不确定这是否总是可行的。

无论如何,我 "solved" 的方法是创建一个单独的查询来评估条件,然后创建一个查询来应用分页(这可以触发另一个查询来计算结果) .

所以使用描述失败案例的要点: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 包含当前 "page" 个结果,并允许您调用 totalCount 以获得结果总数。