4

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

    //selectedGroups 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()内のすべてのグループを(再び)永続化しようとしますか?それとも、それらのグループがすでに存在していることを検出し、新しい関係を更新するだけですか?

「はい、それは再び持続します」の場合、そのコードを正しく機能させるために、この関係にどのように注釈を付ける必要がありますか?

4

1 に答える 1

3

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

編集:コメントに応じて

JPAは、それらが切り離されているため、おそらくそれらを再度永続化しようとします。これは、マージを使用してそれらを再度アタッチするか、それらがデタッチされないようにする必要があることを意味します。

それらが切り離される最も可能性の高い理由は、それらが含まれていたトランザクションの終了です。JTAを使用していて、余分なことを何もしなかったとすると、groupDaoがEJBであるときにaddUserがEJBのメソッドではない場合、トランザクションはgroupDao.find呼び出しで開始し、findが返される瞬間に終了します。デフォルトでは、EJBメソッドがまだ実行されていない場合、EJBメソッドがトランザクションを開始するためです。addUserがEJBのメソッドである場合、addUserがトランザクションを開始し、groupDao.findが既存のトランザクションを使用するため、すべてが1つのトランザクションで発生するため問題ありません。

于 2012-05-13T08:09:37.023 に答える