4

私は Hibernate 3 を使用しており、既存の切り離されたエンティティと関連付けられている新しいエンティティを永続化するときに特定の問題があります。これを説明する最も簡単な方法は、コード サンプルです。FooEntity と BarEntity の 2 つのエンティティがあり、そのうちの BarEntity は多くの FooEntity に関連付けることができます。

@Entity
public class FooEntity implements Foo{

    @Id
    private Long id;

    @ManyToOne(targetEntity = BarEntity.class)
    @JoinColumn(name = "bar_id", referencedColumnName = "id")
    @Cascade(value={CascadeType.ALL})
    private Bar bar;    

}

@Entity
public class BarEntity implements Bar{

    @Id
    private Long id;

    @OneToMany(mappedBy = "bar", targetEntity = FooEntity.class)
    private Set<Foo> foos;
}

Foo と Bar は、さまざまなフィールドの getter を大まかに定義するインターフェイスです。対応する FooImpl クラスと BarImpl クラスがありますが、これらは本質的に注釈のない単なるエンティティ オブジェクトです。

私がやろうとしているのは、FooImpl の新しいインスタンスを構築し、いくつかのフィールドを設定した後にそれを永続化することです。新しい Foo インスタンスの「bar」メンバーは、データベース (session.get(..) 経由で取得) から既存の Bar (ランタイムは BarEntity) に設定されます。FooImpl にすべてのプロパティが設定された後、Apache Dozer を使用して「ドメイン」オブジェクト FooImpl とエンティティ FooEntity の間のマッピングが行われます。Dozer がバックグラウンドで行っていることは、新しい FooEntity をインスタンス化し、一致するすべてのフィールドを設定することです。BarEntity もインスタンス化によって複製され、FooEntity の「bar」メンバーを設定します。

これが発生した後、新しい FooEntity オブジェクトを永続化に渡します。これは例外をスローします:

org.hibernate.PersistentObjectException: detached entity passed to persist: com.company.entity.BarEntity

以下は、発生しているステップのコードです

FooImpl foo = new FooImpl();
//returns at runtime a persistent BarEntity through session.get()
Bar bar = BarService.getBar(1L);
foo.setBar(bar);

...

//This constructs a new instance of FooEntity, with a member 'bar' which itself is a new instance that is detached)
FooEntity entityToPersist = dozerMapper.map(foo, FooEntity.class);

...

session.persist(entityToPersist);

@Cascade アノテーションを削除または変更することでこの問題を解決できましたが、新しい Bar が既にアタッチされている新しい Foo を追加するなど、将来の使用が制限されます。私が見逃している解決策はありますか?Dozer が Foo の子をマップする方法または Hibernate が切り離された子エンティティにどのように反応するかを変更することによって、この問題がこれまでどこかで解決されていなかったとしたら、私は驚くでしょう。

4

2 に答える 2

0

Dozer のマッピングが原因だと思います。FooImpl/FooEntity のプロパティ バーに属性 copy-by-reference="true" を追加してみてください。

于 2011-02-03T10:14:09.477 に答える
0

これにトランザクションがラップされているかどうかを確認していただけますか? 投稿したコードの 2 番目のビットにトランザクションがラップされていない場合、BarEntity永続化を試みるまでに Hibernate セッションから切り離され、言及したエラーが発生します。

于 2011-01-04T16:11:07.583 に答える