7

セキュリティ フレームワークにNimbleShiroを使用していますが、GORM のバグに遭遇しました。それはそう :

User.createCriteria().list { 
   maxResults 10 
} 

10 人のユーザーを返しますが、9 人のユーザーをUser.list(max: 10) 返します。

さらに調査した結果、管理者には2つのロールがあるため、同じユーザー(管理者)createCriteria が2回返されることがわかりました!!! (冗談じゃない)。

複数のロールを持つユーザーは、createCriteria呼び出しで2 回返され、インスタンスUser.listが返されるmax-1ようです (つまり、10 ユーザーではなく 9 ユーザー)。

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

6 に答える 6

4

簡潔で明確ではありませんが、HQL クエリを使用すると、この問題を解決できるようです。Grails のドキュメント(executeQuery セクション)で説明されているように、paginate パラメーターを追加のパラメーターとして executeQuery に追加できます。

User.executeQuery("select distinct user from User user", [max: 2, offset: 2])
于 2010-10-11T17:47:59.530 に答える
3

このようにして、引き続き基準を使用して、リスト/ページ付けパラメーターを渡すことができます

User.createCriteria().listDistinct {
    maxResults(params.max as int)
    firstResult(params.offset as int)
    order(params.order, "asc")
}
于 2010-10-11T21:28:58.727 に答える
2

編集:両方を取得する方法を見つけました!今から本格的に使おう

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 で一般的にページネーションを機能させるために成功裏に使用した 1 つの方法について話すことはできます。

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 が上で言ったように、私はまだ両方の結果を与える 1 つのアトミック ステートメントについて途方に暮れています。私の答えは現在、KoK とほぼ同じであることに気付きました。申し訳ありませんが、プロジェクションの rowCount() の方が読みやすく、まだコメント権限を持っていないことを指摘する価値があると思います:/

最後に: これは、grails の休止状態基準の使用法リファレンスの聖杯です (しゃれは意図されていません)。ブックマークしてください ;) http://www.grails.org/doc/1.3.x/ref/Domain%20Classes/createCriteria.html

于 2011-11-17T20:27:33.843 に答える
1

ここで Ruben と Aaron によって提供された両方のソリューションは、(executeQuery() および listDistinct から) 返されるオブジェクトが ArrayList (最大 max 個のオブジェクトを含む) であり、totalCount プロパティを持つ PagedResultList ではないため、ページネーションに対して「完全に」機能しません。ページネーションを「完全に」サポートするために私が期待するように入力されました。

例がもう少し複雑だとしましょう: 役割に追加の役割名属性があることを前提とする AND b. 文字列「a」を含む Role.rolename を持つ個別の User オブジェクトのみを返したい (ユーザーは、文字列「a」を含む rolename を持つ複数の Roles を持つ可能性があることに注意してください)

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")
    }
}

これは非常に効率が悪いようです。

質問: 1 つの GORM/HQL ステートメントで上記の両方を達成する方法はありますか?

于 2010-11-22T14:45:04.927 に答える
0

使用できます

User.createCriteria().listDistinct {
    maxResults 10
}
于 2010-10-11T10:51:48.230 に答える
0

問題を共有していただきありがとうございます。Kok さんに回答していただきありがとうございます。HQLに書き直す機会がありませんでした。これが私の解決策です(回避策): http://ondrej-kvasnovsky.blogspot.com/2012/01/grails-listdistinct-and-pagination.html

それが役に立つかどうか教えてください(少なくとも誰かにとって)。

于 2012-01-20T13:55:35.183 に答える