2010-12-29 14 views
4

私はHibernate 3を使用しており、既存の分離エンティティとの関連性を持つ新しいエンティティを永続化する際に特に問題があります。これを説明する最も簡単な方法はコードサンプルによるものです。私はBarEntityは多くFooEntityに関連付けることができる2つのエンティティ、FooEntityとBarEntityを有する:Hibernate Beanマッピング(Dozer)の永続性問題

@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とバーは緩く、様々な分野のためのゲッターを定義するインターフェースです。基本的にアノテーションのないエンティティオブジェクトだけである対応するFooImplクラスとBarImplクラスがあります。

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

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

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

はコードで私が削除または@Cascadeアノテーションを変更するいずれかの方法でこの問題を解決することができました

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); 

を発生している段階であるが、それは将来を制限しますたとえば、新しいFooを追加して新しいBarを付け加えているとします。ここに欠けている解決策がありますか? DoooがFooの子をどのようにマップするか、またはHibernateが分離されたChild Entityにどのように反応するかを変更することによって、この問題が以前のどこかで解決されなかった場合、私は驚くでしょう。

答えて

0

ドーザーマッピングが責任を負うと思われます。 FooImpl/FooEntityのプロパティバーにcopy-by-reference = "true"という属性を追加してみてください。

+0

これは私の特定の問題を解決するようです。私が最初にやっていたインタフェースの抽象化の種類を減らすことで、コピー・バイ・リファレンスを使用することで、このケースのための特別なドーザー・マッピングができてしまうと思います。 – BuffaloBuffalo

0

これを回避するトランザクションがあるかどうかを確認できますか?投稿したコードの2番目のビットをラップしたトランザクションがない場合、BarEntityは、永続化しようとするまでにHibernateセッションから切り離されます。

+0

すべて同じトランザクション内で発生しています。これはHibernateTransactionManagerとSpringアノテーションによって制御されます – BuffaloBuffalo

+0

BarEntityにequals()とhashcode()をどのように実装しましたか?私は、equals()またはhashcode()が正しく実装されていないと、HibernateがそのセッションでBarEntityを見つけることができないかもしれないと考えています。 – Mopper

関連する問題