1

通常の実行時またはデバッグ時に.contains()、ドメイン クラスのリレーションシップの 1 つを呼び出しても同じように動作しないという問題があります。hasMany状況は次のとおりです。

2 つのドメイン オブジェクトAB. AhasMany関係がありBます。

class A {
    ...
    static hasMany = [bees: B]
    ...
}

ここで、フィルターの 1 つの実行中に、Spring セキュリティ サービスから現在のユーザーを取得します。このユーザーには、 の 1 つのインスタンスも含まれていますB。私のフィルターがすべきことはB、ユーザーの のインスタンスが のインスタンスに含まれているかどうかを確認することですA

のインスタンスが実際には同じオブジェクトを参照していると仮定しBます (それらは同じであるため)。

さて、問題が発生します。呼び出し:

if (instanceOfA.bees.contains(user.instanceOfB)) {
    println 'success'
} else {
    println 'failure'
}

failure通常の(またはコードをステップ実行せずにデバッグする)実行中に出力されます。ただし、そこにブレークポイントを置いてコードをステップスルーすると、正しく実行されてcontains()出力されsuccessます。

これを解決しようとしても実装equalsしましたが、同じ動作をします。hashCodecompareTo

4

4 に答える 4

3

これは通常、遅延読み込みまたはキャッシュが原因です。使用するinstanceOfA.bees.id.contains(user.instanceOfB.id)と、常に機能します。

于 2013-09-03T16:44:17.710 に答える
2

オブジェクトuser.instanceOfBが休止状態のプロキシ オブジェクトであるため、実際のB ではない可能性があります。これは、デバッガーまたは印刷を使用して確認できますuser.instanceOfB.getClass()

を使用GrailsHibernateUtil.unwrapIfProxy(proxyObject)して、プロキシから実際のオブジェクトを取得できます。

于 2013-09-03T16:59:05.393 に答える
1

そのため、Groovy 変換アノテーションの 1 つを使用するとうまくいくようです。単に追加するだけです:

// uid is a uniqe UUID we use to identify with other systems.
@EqualsAndHashCode(includes = ["id", "uid"])

トリックを行います。IDE が生成したメソッド (同じフィールドを使用) がそうしなかったのは少し奇妙に思えます...

于 2013-09-04T05:29:39.807 に答える
1

私はHQLでこれを行います:

A.executeQuery("select a from A a join a.bees as b where b = :b and a = :a", [a: instanceOfA, b: user.instanceOfB])
于 2013-09-03T17:33:06.267 に答える