2016-08-11 7 views
0

の更新の関係は、私は2つのエンティティ価格OneToOneとしてマッピング>PriceDetail < -1 ---- 1-持っています。JPA:新しい親エンティティ

この関係のさまざまなシナリオをどのように処理できますか。だから私はいつも新しい価格と新しいpriceetail、 がほしいと思うケースがあるが、私はまた、新しい価格だけを作り、(以前の価格実体からのデータで)pricetailを更新することができるだろう。 私の現在の解決策は、pricetail-entityを削除することです.personetail-entityを更新するにはどうしたらいいですか?

セーブ・メソッド
@Entity 
class Price { 

    @OneToOne(cascade=CascadeType.ALL,mappedBy = "price") 
    private PriceDetail priceDetail; 
} 

@Entity 
class PriceDetail { 

    @OneToOne 
    private Price price; 
} 

:理由は価格・エンティティでCascadeType.ALLアノテーションの

EntityManage em = getEntityManager(); 

for (Price price : getAllPrices()){ 

    Price oldPrice = Price.getById(price.getId());    

    if (!oldPrice.equals(price)){ //if we have price-changes 

    if (PriceCatalog.entryExists(oldPrice)){ //if the current-price is in a catalog 

     //current solution: remove entry from PriceDetail, but i want to update PriceDetail-Entity, pointing 
     //to the newly created price 
     em.remove(oldPrice.getPriceDetail()); 
     em.commitTransaction(); 

     oldPrice.setActive(false); //referenced price in PriceCatalog is now inactive     

     //sets id null, so that a new price-entity is created 
     price.setId(null);    
     price.setActive(true);       
     em.persist(price); //also inserts a new price-detail 

    }else { 
     em.merge(price); 
    } 
    }       
} 
em.commitTransaction(); 

、JPAは新しいPriceDetail-エンティティを挿入しようとします。

アプローチ1:

price.getPriceDetail().setId(oldPrice.getPriceDetail().getId()); 

- >エラー:pricedetailに挿入ユニーク制約に違反:1つの作品に近づき、その後

//ommit cascade 
    @OneToOne(mappedBy = "price") 
    protected PriceDetail priceDetail; 

が、作成:キーはすでに

アプローチ2が存在します完全な新しい価格は次のようになります。 同期中に、カスケードとマークされていない関係を通じて新しいオブジェクトが見つかりました。PERSIST

答えて

1

アプローチ2は、あなたの場合はオプションではありません、これは双方向の1対1の関連付けを行うための正しいマッピングです:

//you must do this to handle the bidirectional association 
    @OneToOne(mappedBy = "price") 
    protected PriceDetail priceDetail; 

今の問題は、次のとおりです。価格は、EntityManagerの、新しいエンティティですprice.getpriceDetail()でpersiteオペレーションを呼び出すのは、カスケード持続が自動的にトリガされるため(カスケードマージではなく)、次のような奇妙な動作を避けるためです。

EntityManage em = getEntityManager(); 

for (Price price : getAllPrices()){ 

    Price oldPrice = Price.getById(price.getId());    

    if (!oldPrice.equals(price)){ //if we have price-changes 

    if (PriceCatalog.entryExists(oldPrice)){ //if the current-price is in a catalog 

     //current solution: remove entry from PriceDetail, but i want to update PriceDetail-Entity, pointing 
     //to the newly created price 
     //em.remove(oldPrice.getPriceDetail()); 
     //em.commitTransaction(); 

     oldPrice.setActive(false); //referenced price in PriceCatalog is now inactive     

     PriceDetail priceDetailold = price.getPriceDetail(); 
     price.setPriceDetail(null); 
     priceDetailold.setPrice(null); 
     //sets id null, so that a new price-entity is created 
     price.setId(null);    
     price.setActive(true); 

     em.persist(price); //inserts a new price 
     price.setPriceDetail(priceDetailold); 
     em.merge(price);// attach the pricedetail to the price 
    }else { 
     em.merge(price); 
    } 
}      
} 
em.commitTransaction(); 
+0

このように、これは例外として動作しています。知っておいて、あなたの提案を将来見守ります。どうもありがとう! – Steve

関連する問題