2017-05-29 7 views
2

我々はhibernate4:4.3.8.1プラグインを持つgrails 2.5.5アプリケーションを持っています。左結合の基準はすべての多対多関連を読み込みません

我々が持っている、多くの関係を持っているドメインを照会すると、基準-APIと左に参加して、GORMはすべて持っている、多くの関連をロードしません。

例:

class Role { 
    String name 
} 

class User { 
    String name 
    static hasMany = [roles: Role] 
} 

テストデータ:

def role1 = new Role(name: "Role1").save() 
def role2 = new Role(name: "Role2").save() 

def user = new User(name: "User") 
user.addToRoles(role1) 
user.addToRoles(role2) 
user.save() 

我々は内側の参加で結果を照会すると予想され、ユーザのすべてのロールがロードされるように、それは動作します:

User.withNewSession { 
    def user = User.withCriteria({ 
     roles { 
      eq "name", "Role1" 
     } 
    }).first() 
    assert user.roles.size() == 2 
} 

しかし、左の参加をキシにする場合、ユーザーの結果のみが照会「ROLE1」が含まれています。 「Role2」が読み込まれません。

User.withNewSession { 
    def user = User.withCriteria({ 
     roles(CriteriaSpecification.LEFT_JOIN) { 
      eq "name", "Role1" 
     } 
    }).first() 
    assert user.roles.size() == 2 //This breaks! Only Role1 is loaded. 
} 

これがなぜ壊れているのか考えてください。

注:このコードは、ロールが正しくロードされていない場合にのみ機能します。だから私はwithNewSessionをこの例で使うのです。

答えて

0

私はまだ家にないんだけど、私はあなたがthis thread


[OK]をして、私は最終的にはより多くのそれについて見ていくつかの暇な時間を持っているだけのようではなく、直接クラス変数を使用してのエイリアスを使用すべきだと思いますさらに。申し訳ありませんが、私の最初の答えはあなたを助けません。

問題は、GORMがコードをSQLに変換する方法が、あなたが期待するものではないということです。です。

あなたは上のSQLログを有効にしようと、あなたのDBにそれをコピー&ペーストした場合は、私が何を意味するのか知っていますよ。このクエリは、role.name = Role1のエンティティのみを返します。このため、「GORMはすべてのhas-many関連をロードしません」ということになります。このため

クイックフィックスは、より多くのuser.refreshを行うことによって、一度インスタンスをリロードすることです()。

PS:withNewSessionはこの件に関して、あなたには何も助けないないので、あなたにも、あなたのコメントをあなたのコードから

+0

おかげで、それを削除することがありますが、アプローチは、同じ結果があります。 'User.withNewSession { を\t DEFユーザー= User.withCriteria({ \t \t createAlias( 'ロール'、 'rolesJoin'、JoinType.LEFT_OUTER_JOIN) \t \t EQ "rolesJoin.name"、 "ROLE1" \t})。最初の() \tアサートuser.roles.size()== 2 //これが壊れます! Role1のみがロードされます。 } ' – gregorr

+0

あなたの2番目の答えに感謝します。私はあなたが何を意味しているのか知っていて、なぜ1つの役割しかロードされていないのか理解できますが、それは休眠/ゴミのバグです。 無効なオブジェクトを返す有効なcriteria-statementを書き込みました。さらに、間違った結果がキャッシュされ、他のすべてのステートメントは同じ誤った結果を返します。私はこれを(私の目で)間違った行動を避ける方法を探しています。 – gregorr

+0

パフォーマンスの問題が発生した場合、refresh()は実際にはオプションではありません。 – gregorr

関連する問題