2016-08-11 6 views
0

У меня есть два объекта Цены < -1 ---- 1->PriceDetail отображаются в OneToOne.JPA: отношения обновления для новой родительской сущности

Как я могу обрабатывать различные сценарии для этого отношения. поэтому у меня есть случаи, когда я всегда хочу новую цену и новую цену, , но я также смог бы создать новую цену и обновить priceetail (с данными предыдущего объекта цены). Мое текущее решение заключается в удалении объекта costetail, как это можно сделать с обновлением объекта costetail?

@Entity 
class Price { 

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

@Entity 
class PriceDetail { 

    @OneToOne 
    private Price price; 
} 

копи-метод:

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

из CascadeType.ALL-аннотаций в Прайс-Сущности, JPA пытается вставить новый PriceDetail-Entity.

подход 1:

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

-> Ошибка: вставить в pricedetail нарушает Уникально ограничение: Ключ уже существует

подход 2:

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

затем подойдите 1 работает, но и создание полная новая цена приводит к: Во время синхронизации новый объект был найден через связь, которая не была отмечена каскадом PERSIST

ответ

1

подход-не вариант в вас случае, это правильное отображение делать двунаправленную один-к-одному ассоциацию:

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

Теперь проблема: цена является новым объектом, то EntityManager вызовет функцию persit на price.getpriceDetail(), потому что каскадное сохранение запускается автоматически (а не каскадное слияние), чтобы избежать этого странного поведения, вы можете сделать следующее.

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

 Смежные вопросы

  • Нет связанных вопросов^_^