1

user と credit_card エンティティがあり、user には credit_card のコレクションがあります。私が持っているこれらのエンティティの両方の主キーはバイト[]です。

最初のセッション: - 新しいセッションを開始しました。- users テーブルで条件クエリを実行します。これは実際に DB に移動し、user + credit_cards を取得し、最後に userObj というユーザー オブジェクトを取得します。- セッションを閉じます。

2 番目のセッション: - 別のセッションを開きました。- session.buildLockRequest(LockOptions.NONE).lock(userObj); を呼び出そうとしています。

休止状態は切り離されたオブジェクトを再接続しようとしますが、次のエラーが発生します:

org.hibernate.HibernateException: reassociated object has dirty collection reference
at org.hibernate.event.def.OnLockVisitor.processCollection(OnLockVisitor.java:71)
at org.hibernate.event.def.AbstractVisitor.processValue(AbstractVisitor.java:122)
at org.hibernate.event.def.AbstractVisitor.processValue(AbstractVisitor.java:83)
at org.hibernate.event.def.AbstractVisitor.processEntityPropertyValues(AbstractVisitor.java:77)
at org.hibernate.event.def.AbstractVisitor.process(AbstractVisitor.java:144)
at org.hibernate.event.def.AbstractReassociateEventListener.reassociate(AbstractReassociateEve    ntListener.java:101)
at   org.hibernate.event.def.DefaultLockEventListener.onLock(DefaultLockEventListener.java:82)
at org.hibernate.impl.SessionImpl.fireLock(SessionImpl.java:774)
at org.hibernate.impl.SessionImpl.fireLock(SessionImpl.java:766)
at org.hibernate.impl.SessionImpl.access$600(SessionImpl.java:156)

休止状態のコードでデバッグしようとしたところ、渡されたオブジェクトのコレクション (credit_cards) が実際にユーザー (user1) によって所有されているかどうかを休止状態がチェックしようとすることがわかりました。

そのため、休止状態のコードのどこかで、渡されたオブジェクト (user1) の主キーとスナップショット オブジェクトと呼ばれる別のオブジェクトのequals メソッドとの等価性をチェックしているようです。byte[] は本質的に配列であるため、等しいチェックに失敗し、上記のエラーがスローされます。上記の作業を 1 回のセッションで実行できることはわかっていますが、これは単なるシナリオです。

Long/Integer を主キーとして使用してみましたが、同等性チェックに合格するため、問題なく動作します。

Hibernate バージョン: 3.6.9.Final (4.1.1.Final バージョンも調べてみましたが、このエラーをスローするファイル/コードは変更されていません) DB: SQL サーバー

それは休止状態の問題ですか、それとも何か間違っていますか?

4

2 に答える 2

1

Hibernate の問題ではありません。ID のクラスは、hashCode と equals を適切に実装する必要があります。byte[]ないため、有効な ID クラスではありません。byte[] を ID として使用することは、IMO では非常に悪い考えです。ロングは本当に良いアイデアです。本当にバイト配列を保持したい場合は、それをカスタム型にラップするか、Base64 または Hex エンコーディングを使用して文字列に変換します。

于 2012-03-15T15:13:59.093 に答える
1

byte[] の代わりに String を主キーとして使用します。同じ値を運ぶことができ、equals メソッドを渡します

String myId = new String(bytes);

myId.getBytes();

これは休止状態の問題ではありません。

于 2012-03-15T15:08:50.417 に答える