0

ID ジェネレーターが割り当てられている (つまり、自動生成されない) ドメイン クラスを使用して grails アプリケーションを構築しています。ドメイン クラス Parentstatic hasMany = [children: Child]とドメイン クラス Child があるとします。

を使用して Parent のインスタンスを見つけようとしていますが、ID 0 を持つこのセッションに関連付けられた Child インスタンスが既に存在することを示すNonUniqueObjectExceptionParent.findWhere(propertyMap)を取得しています。私の propertyMap には ID のエントリが含まれていません。

現在、ID を設定せずにセッションで 1 つのクラスの 2 つのインスタンスを保存しようとすると、常にこのエラーが発生することに慣れています。ID は自動生成されないため、デフォルトでゼロに設定されます。これにより、最初の ID は保存され、2 番目の ID は最初の ID の複製であるため、エラーがスローされます。ここで驚いたのは、インスタンスを保存するのではなく、インスタンスを見つけようとしているということです...この動作の原因と、プロパティマップを使用して検索中にそれを回避する方法を知っている人はいますか?

4

2 に答える 2

1

これはグルーヴィーな構文糖の問題であることが判明しました。私はfindWhereのようなものを呼んでいました

Parent.findWhere([ firstProperty: "firstValue", secondProperty: "SecondValue" ])

しかし、どうやら私は使用する必要があります

Parent.findWhere( firstProperty: "firstValue", secondProperty: "SecondValue" )

(角括弧がないことに注意してください)。なぜこれが違いを生んだのかはわかりませんが、findWhere は期待どおりに機能するようになりました。なぜこのように振る舞うかを知っているかもしれない人への余分なポイント。

于 2012-07-11T16:42:27.307 に答える
0

ご存知のように、Hibernate には、セッションで同じ ID を表す 2 つのオブジェクトを使用できないという強い制約があります。おそらく気付いていないかもしれませんが、save()操作、更新、動的クエリのいずれであっても、同じ Hibernate セッションに同じ ID を持つ 2 つのオブジェクトがある場合、Hibernate はそのような例外を発生させます。セッションに同じようなオブジェクトがもう 1 つあることを確認してください。

ここでは次のように述べています。

GORM を使用して何らかの方法でドメイン インスタンスを取得すると、たとえば get() メソッドや任意の種類のクエリを介して、オブジェクトは自動的にセッションに関連付けられます。

おそらく、親オブジェクトを参照する子オブジェクトがセッションに存在します (これにはまだ ID がありません)。親オブジェクトがセッションに移動する前にIDを与えるか、親を参照する子をセッションに保存しないようにする以外に、これ以外のエレガントな方法はありません。他の方法はevict()、次のようなオブジェクトで使用することですsession.evict(object)。しかし、それは良いことではありません。

乾杯!

于 2012-07-03T19:56:28.117 に答える