2012-05-11 9 views
4

JPAは、すでに永続的な(かつ非デタッチされている)エンティティ上で持続的にカスケードしようとしますか?JPAは永続性エンティティと既に永続化エンティティをカスケードしようとしますか?

物事を明確にするために、ここに私の状況です:私は、新しいユーザー存続したい:だから

public void addUser(){ 
    //User is an entity that is related to many Groups 
    //The relationship on User side is marked with cascade persist 
    User user = new User(); 
    user.setName("foo"); 
    user.setGroups(new ArrayList<Groups>()); 

    //selectedUsers is an List of Groups previously created with persistent Groups 
    for(Group g : this.selectedGroups){ 
     user.getGroups().add(this.groupDao.find(g.getId())); 
    } 
    //At this point, User.getGroups() is a list of Managed Entities 

    //What happens on the following line? 
    userDao.persist(user); 
} 

を、どうなりますか? JPAはuser.getGroups()内のすべてのグループを永続化しようとしますか?あるいは、それらのグループがすでに存在していることを検出し、新しい関係を更新するだけですか?

「はい、それはもう一度持続します」の場合、この関係にアノテーションを付けてコードが正しく機能するようにするにはどうすればよいですか?

+0

試してみるとどうなりますか? –

+0

私がテストした限り、エンティティを再び永続化しようとします。しかし、私が何か間違っているかどうかわかりません... –

+0

JPA 2仕様では、3.2.2項「Xが既存の管理対象エンティティの場合、永続操作で無視されます」と記載されています。だから間違ったことをやっている。 –

答えて

3

JPAは新しいグループと既に永続化されているグループの違いを検出し、新しいグループのみを維持します。

編集:コメントへの応答で

JPAは、おそらく彼らは切り離されているため、再びそれらを持続しようとします。これは、マージを使用してそれらを再度添付するか、またはそれらが分離されないようにする必要があることを意味します。

それらが切り離される最も一般的な理由は、それらが含まれていたトランザクションの終了です。あなたがJTAを使用していて、何も追加しなかったとすると、addUserがEJBのメソッドではなく、groupDaoがEJBである場合、トランザクションはgroupDao.findコールで始まり、findが返す瞬間を終了します。デフォルトでは、EJBメソッドはすでに実行中でなければトランザクションを開始するためです。 addUserがEJBのメソッドであれば、addUserはトランザクションを開始し、groupDao.findは既存のトランザクションを使用してすべてが1つのトランザクション内で行われるため、問題はないはずです。

+0

私がテストした限り、エンティティを再び永続化しようとします。しかし、私は何か間違っているかどうかわかりません... –

+0

あなたの問題の最も可能性の高い原因に対処するために私の答えを展開しました。 – Eelke

+0

問題は、永続的なエンティティを使用していたが、EntityManagerのトランザクションの外で、したがってtouが切断されたためです。情報をありがとう。 –

関連する問題