2016-10-23 4 views
0

親を更新しようとしたときにEntityExistExceptionが発生し、子がDTOです。これを修正するにはどうすればいいですか?親にマージを呼び出そうとしましたが、運がありません。私はSpringデータjpaと休止状態を使用しています。Spring Data/hibernate子DTOオブジェクトと@MapsIdの更新

私は次のことをやっている私のRESTサービスで
@Entity 
class Parent { 
    @Id 
    private int id; 

    @OneToOne(cascade = CascadeType.ALL, mappedBy = "parent") 
    private Child child; 

    // getters and setters 
} 

@Entity 
class Child { 
    @Id 
    private int id; 

    private String data; 

    @MapsId 
    @OneToOne 
    private Parent parent; 

    // getters and setters 
} 

Child child = new Child(data); // data from request 
Parent parent = parentRepositoryService.getParent(id); 
parent.setChild(child); 
parentRepositoryService.update(parent); 

parentRepositoryService.class

class ParentRepositoryService { 
    public void update(Parent parent) { 
     parent.getChild().setParent(parent); // necessary to prevent Exception 
     parentRepository.save(parent); 
    } 
} 

私はこの問題は、子オブジェクトからのセッションですでにあるということだと思います"parentRepositoryService.getParent(id)"コール。次に、Childオブジェクトがセッション外で作成され、古いChildオブジェクトと新しいChildオブジェクトの不一致が発生します。私は、手動でセッションベースのChildオブジェクトをリクエストデータから更新する必要がなく、Childエンティティに対してmysql "insert ... duplicate key update"と同等の機能を実行したいと考えています。

あなたは子供C1を持つ親Pをロード:私はここだと思う

答えて

0

は何が起こるかです。したがって、次のオブジェクトがあります。

P -> C1 
C1 -> P 

ここで、矢印は参照を意味します。

は今、あなたは新しい子C2を作成し、Pの子として設定して、以下のオブジェクトで終わる:C1はまだPを参照すること

P -> C2 
C1 -> P 
C2 -> P 

注意。セッションがフラッシュされると、Hibernateは子の参照を使用して関係を保持し、例外を受け取ります。Pは2人の子によって参照されるためです。

これを修正するには、古い子から親に参照を設定解除するには、削除することもできます。これは本当にただ

parent.getChild().setParent(parent) 

として、Parentクラスの内部で起こるべき古い子から親への参照を削除するお勧めしますどのようにParent.setChild

+0

の一部である必要がありますか? oldChild.setParent(null)を呼び出そうとしましたが、まだ例外があります。 "EntityExistsException:同じ識別子値を持つ別のオブジェクトが既にセッションに関連付けられていました" – rodney757

+0

C1とC2が同じPK(Parent.id)を使用しているが、異なるオブジェクトであるため、これが起こっていると思います。 – rodney757

+0

はい、おそらく、親と子の間で共有されているPKのためです。 1つの解決策は、残りの要求に応答して既存の子を更新することである。 –

関連する問題