【问题标题】:GORM createCriteria and list do not return the same results : what can I do?GORM createCriteria 和 list 不返回相同的结果:我该怎么办?
【发布时间】:2011-04-23 18:12:15
【问题描述】:

我正在使用NimbleShiro 作为我的安全框架,我刚刚遇到了一个GORM 错误。确实:

User.createCriteria().list { 
   maxResults 10 
} 

返回 10 个用户,而 User.list(max: 10) 返回 9 个用户

经过进一步调查,我发现createCriteria 返回两次相同的用户(admin)因为admin有2个角色!!! (我不是在开玩笑)。

createCriteria 调用中,任何具有超过 1 个角色的用户似乎都将返回两次,User.list 将返回 max-1 实例(即 9 个用户而不是 10 个用户)

我可以使用什么解决方法来返回 10 个唯一用户?

这很烦人,因为我无法正确使用分页。


我的域类是:

class UserBase { 
   String username 
   static belongsTo = [Role, Group] 
   static hasMany = [roles: Role, groups: Group] 
   static fetchMode = [roles: 'eager', groups: 'eager'] 
   static mapping = { 
     roles cache: true, 
     cascade: 'none', 
     cache usage: 'read-write', include: 'all' 
   } 
}

class User extends UserBase { 
  static mapping = {cache: 'read-write'} 
} 

class Role { 
  static hasMany = [users: UserBase, groups: Group] 
  static belongsTo = [Group] 
  static mapping = { cache usage: 'read-write', include: 'all' 
    users cache: true 
    groups cache: true 
  } 
} 

【问题讨论】:

  • 你最终的实现是什么?因为我也有同样的问题。非常感谢

标签: grails grails-orm shiro nimble


【解决方案1】:

你可以使用

User.createCriteria().listDistinct {
    maxResults 10
}

【讨论】:

  • 几乎可以工作 :)ListDistinct 将返回 9 个用户而不是 10 个(删除重复的用户)。但是,例如,如何使用带有偏移参数的分页。
  • 这可能会有所帮助:grails.org/doc/latest/api/grails/orm/…
  • 不同投影的问题是您只保留指定不同的“列”或属性。
【解决方案2】:

不太简洁明了,但使用 HQL 查询似乎是解决此问题的一种方法。如Grails documentation(executeQuery 部分)所述,分页参数可以作为额外参数添加到 executeQuery。

User.executeQuery("select distinct user from User user", [max: 2, offset: 2])

【讨论】:

  • 非常感谢。有用 !!你知道这个错误是否存在 JIRA 问题吗?
  • 关于为什么 listDistinct 只过滤掉内存中的重复项的详细解释可以在 Hibernate FAQ 中找到:community.jboss.org/wiki/…
【解决方案3】:

这样你仍然可以使用条件并传入列表/分页参数

User.createCriteria().listDistinct {
    maxResults(params.max as int)
    firstResult(params.offset as int)
    order(params.order, "asc")
}

【讨论】:

  • 它不仅是关于提供分页参数,它是关于拥有一个真正的 PagedResultList 并设置了 totalCount 属性...
【解决方案4】:

Ruben 和 Aaron 提供的两种解决方案仍然不能“完全”用于分页 因为返回的对象(来自 executeQuery() 和 listDistinct)是一个 ArrayList (其中最多包含最大对象),而不是具有 totalCount 属性的 PagedResultList 正如我所期望的那样填充“完全”支持分页。

假设这个例子稍微复杂一点: 一种。假设角色有一个额外的角色名称属性和 湾。我们只想返回具有包含字符串“a”的 Role.rolename 的不同用户对象 (请记住,一个用户可能有多个角色,其角色名称包含字符串“a”)

要通过 2 个查询完成此操作,我必须执行以下操作:

// First get the *unique* ids of Users (as list returns duplicates by
// default) matching the Role.rolename containing a string "a" criteria
def idList = User.createCriteria().list {
  roles {
    ilike( "rolename", "%a%" )
  }
  projections {
    distinct ( "id" )
  }
}

if( idList ){
  // Then get the PagedResultList for all of those unique ids
  PagedResultList resultList =
    User.createCriteria().list( offset:"5", max:"5" ){
      or {
         idList.each {
           idEq( it )
         }
      }     
      order ("username", "asc")
    }
}

这似乎非常低效。

问题:有没有办法用一个 GORM/HQL 语句来完成上述两个任务?

【讨论】:

  • 你可以使用 'in' "id" idList 代替循环和 idEq(it)
【解决方案5】:

编辑:找到了两种方法!现在完全会用它

http://www.intelligrape.com/blog/tag/pagedresultlist/

If you call createCriteria().list() like this
def result=SampleDomain.createCriteria().list(max:params.max, offset:params.offset){
// multiple/complex restrictions
   maxResults(params.max)
   firstResult(params.offset)
} // Return type is PagedResultList
println result
println result.totalCount

您将以漂亮的 PagedResultList 格式获得所需的所有信息!

/编辑

不幸的是,我不知道如何在同一个调用中获得完整结果和最大/偏移分页子集的组合。 (哪位大神能解惑?)

不过,我可以谈谈我成功使用的一种方法,以使分页在 grails 中普遍工作。

def numResults = YourDomain.withCriteria() {
    like(searchField, searchValue)
    order(sort, order)
    projections {
      rowCount()
    }
}

def resultList = YourDomain.withCriteria() {
    like(searchField, searchValue)
    order(sort, order)
    maxResults max as int
    firstResult offset as int
}

这是我用来启动和运行分页的示例。正如 KoK 上面所说,我仍然不知道给出两个结果的单个原子语句。我意识到我的答案现在或多或少与 KoK 相同,抱歉,但我认为值得指出的是,预测中的 rowCount() 阅读起来稍微清晰一些,而且我还没有评论权限:/

最后:这是 grails hibernate 标准用法参考的圣杯(不是双关语);书签它;) http://www.grails.org/doc/1.3.x/ref/Domain%20Classes/createCriteria.html

【讨论】:

    【解决方案6】:

    感谢您分享您的问题和 Kok 的回答。我没有机会将其重写为 HQL。这是我的解决方案(解决方法):http://ondrej-kvasnovsky.blogspot.com/2012/01/grails-listdistinct-and-pagination.html

    请告诉我这是否有用(至少对某人有用)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-12-31
      • 2010-10-23
      • 1970-01-01
      • 1970-01-01
      • 2017-01-04
      相关资源
      最近更新 更多