1

休止状態の 3.6.3.Final を使用しています。次のように定義された一方向の ManyToOne を持つ 2 つのリレーショナル エンティティ A と B があります。


@Entity public class A {
...
@Version @Column ( name = "ChangeNumber" )
public Long getVersion() { return version; }
@ManyToOne @JoinColumn( name = "B_ID" )
public B getRelationalB() { return relationalB; }
...
}

@Entity public class B {
@Version @Column ( name = "ChangeNumber" )
public Long getVersion() { return version; }
....
}

ここで、すでに pk id = 1 で db に永続的な B インスタンスがあり、次の操作を行っているとします。


A a = new A();
a.setRelationalB( new B( 1 ) );
session.saveOrUpdate( a ) ;
有名な「TransientObjectException: object references an unsaved transient...」例外をスローします。驚くべきことに、@Version @Column を削除するか @Transient にすると、上記のコードは問題なく動作します。なぜ私がこの行動を観察しているのか分かりますか?

4

2 に答える 2

1

問題は、データベースにあるエンティティ B を使用していないことです

A a = new A();
// you're instantiating a "new" B with id 1, this is not the same 
// as the "object" you have in the database.
a.setRelationalB( new B( 1 ) );   
session.saveOrUpdate( a ) ;

問題は、作成した新しい B がデータベースに保存されているものと同じであることを hibernate が認識できないことです。この背後にある理由を知りたい場合は、Unit of Workパターンについて読んでください。

のようなことをしてみてください

B b = sessions.get(B.class, 1)
A a = new A();
a.setRelationalB( b );
session.saveOrUpdate( a ) ;

別のポイント: 両方のオブジェクトの新しいインスタンスを一度に保存したい場合は、カスケードを実行する必要があります。

于 2011-05-29T19:35:47.800 に答える
0

@Version 列を追加した後も、「オブジェクトは保存されていないトランジェントを参照しています...」という例外がたくさんありました。これが私の場合の解決方法です。

私のシナリオでは、問題は外部キーにありました。コードは、参照されたオブジェクトをロードする代わりに、新しいインスタンスを作成し、 Hibernate が実際のインスタンスを見つけられるように主キーを設定するように記述されています。繰り返しますが、 @Version の前は問題なく機能していました。

説明:

Bid を持つクラス のオブジェクトが1データベースに存在し、 の新しいインスタンスを保存しているとしますA

  • 以前(ダメ)( @Version を追加した後に例外が発生していた):

    a.setB(新しい B(1));

    sf.getCurrentSession().save(a);

  • 修正済み (正常に動作) - 問題なく @Version を使用:

    a.setB((B) sf.getCurrentSession().get(B.class, 1));

    sf.getCurrentSession().save(a);

Hibernate をデバッグすると、@Version 列が存在する場合に追加のチェックが行われることがわかりました。

したがって、このエラーが発生した人は、参照しようとしているオブジェクトをロードしていないか (これはとにかくより良い方法です) 、またはB(たとえば)の新しいインスタンスを実際に保存しようとしていますが、保存していませんでした。そのためのカスケード保存を構成します。

于 2013-05-30T20:52:36.257 に答える