2013-06-13 2 views
1

Я хочу, чтобы создать и удалить одну из ProductPrice, обновление работает правильно, но другие дает исключение,Java Hibernate JPA Удаление OneToMany связь и MapKeyJoinColumn связь объекта

КЛАСС ПРОДУКТА

public class Product extends GenericEntity { 
    @OneToMany(fetch=FetchType.EAGER, mappedBy = "product", targetEntity = ProductPrice.class, cascade = {CascadeType.ALL}, orphanRemoval=true) 
    @Fetch(FetchMode.SUBSELECT)  
    @Cache(usage = CacheConcurrencyStrategy.READ_WRITE, region="ncStandardElements") 
    private List<ProductPrice> productPrices = new ArrayList<ProductPrice>(); 

    @OneToMany(fetch=FetchType.EAGER, mappedBy = "product", targetEntity = ProductPrice.class) 
    @Fetch(FetchMode.SUBSELECT)  
    @MapKeyJoinColumn(name="CURRENCY_ID") 
    @Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE, region="ncStandardElements") 
    private Map<Currency, ProductPrice> productPriceMap = new HashMap<Currency, ProductPrice>(); 
} 

КЛАСС ПРОДУКЦИИ

public class ProductPrice extends GenericEntitySimple { 

    @ManyToOne(targetEntity = Product.class, optional=false) 
    @JoinColumn(name = "PRODUCT_ID", referencedColumnName = "ID") 
    private Product product; 
} 




public void removeProductPrice(ProductPrice price){ 
    Product p = price.getProduct(); 
    //Map<Currency, ProductPrice> productPriceMap = p.getProductPriceMap(); 
    //productPriceMap.remove(price); 

    List<ProductPrice> prices = p.getProductPrices(); 
    prices.remove(price); 
    p.setProductPrices(prices); 
    productDao.merge(p); 
} 

Если цена создается на той же сессии, операция удаления прошла успешно, однако, если он создан до нынешней сессии, он бросает эту ошибку:

Jun 13, 2013 3:26:29 PM org.apache.catalina.core.StandardWrapperValve invoke 
SEVERE: Servlet.service() for servlet appServlet threw exception 
org.hibernate.ObjectNotFoundException: No row with the given identifier exists: [com.netasoft.commerce.framework.catalog.model.ProductPrice#220] 
    at org.hibernate.impl.SessionFactoryImpl$2.handleEntityNotFound(SessionFactoryImpl.java:435) 
    at org.hibernate.event.def.DefaultLoadEventListener.load(DefaultLoadEventListener.java:233) 
    at org.hibernate.event.def.DefaultLoadEventListener.proxyOrLoad(DefaultLoadEventListener.java:285) 
    at org.hibernate.event.def.DefaultLoadEventListener.onLoad(DefaultLoadEventListener.java:152) 
    at org.hibernate.impl.SessionImpl.fireLoad(SessionImpl.java:1090) 

я не получаю MapKeyJoinColumn полностью, и я не могу найти документацию об этой ситуации. Я думаю, что кеш-список карт вызывает эту ошибку. Также одобрены любые подготовленные предложения по документации.

ответ

0

Последнее, что я нашел, это то, что;

Настоящая проблема - это тот же объект в двух разных кешах списка. Таким образом, когда вы изменили один из них, это вызывает ошибку в соответствии с выбранным вами методом FetchType.

Если определить FetchTypes, как FetchType.Eager, FetchType.SUBSELECT и CacheConcurrencyStrategy.READ_WRITE, вы можете легко Cr на изменяющихся объектах в два стороне кэша! то есть вы хотите удалить одну из цен, вы должны удалить ее с productPriceMap & productPrices тоже. Затем merge product; и он уже закончился!

@OneToMany(fetch=FetchType.EAGER, mappedBy = "product", targetEntity = ProductPrice.class, cascade = {CascadeType.ALL}, orphanRemoval=true) 
    @Fetch(FetchMode.SUBSELECT)  
    @Cache(usage = CacheConcurrencyStrategy.READ_WRITE, region="ncStandardElements") 
    private List<ProductPrice> productPrices = new ArrayList<ProductPrice>(); 

    @OneToMany(fetch=FetchType.EAGER, mappedBy = "product", targetEntity = ProductPrice.class) 
    @Fetch(FetchMode.SUBSELECT)  
    @MapKeyJoinColumn(name="CURRENCY_ID") 
    @Cache(usage = CacheConcurrencyStrategy.READ_WRITE, region="ncStandardElements") 
    private Map<Currency, ProductPrice> productPriceMap = new HashMap<Currency, ProductPrice>(); 

CRUD СЛУЖБЫ ПО

public void removeProductPrice(ProductPrice price){ 
    Product p = price.getProduct(); 
    Map<Currency, ProductPrice> productPriceMap = p.getProductPriceMap(); 
    productPriceMap.remove(price); 

    List<ProductPrice> prices = p.getProductPrices(); 
    prices.remove(price); 
    p.setProductPrices(prices); 

    p.removeProductPriceMap(price); 

    productDao.merge(p); 
} 

public void saveProductPrice(ProductPrice price, boolean isNew){ 
    Product p = price.getProduct(); 
    List<ProductPrice> prices = p.getProductPrices(); 
    if(isNew){ 
     prices.add(price); 
    } 
    else{ 
     int i = 0; 
     for (ProductPrice tp: prices){ 
      if (tp.getId() == price.getId()){ 
       prices.set(i, price); 
       break; 
      } 
      i++; 
     } 
    } 

    p.setProductPrices(prices); 
    productDao.merge(p); 
} 
0

Я предполагаю, что перед вызовом removeProductPrice() вы открываете сеанс и начинаете транзакцию.

В методе removeProductPrice() загрузите объект productPrice в контекст персистентности, выполнив get(). Мол,

ProductPrice price = productPriceDao.get(price.getPriceId()); 

// Then your logic to delete. 

Я подозреваю, что переданный ProductPrice объект метода removeProductPrice() нет в контексте сохранения состояния сеанса.

Можете ли вы опубликовать полную трассировку стека, которая показывает точную строку, вызывающую исключение.

+0

'productDao.merge (р);' ошибка линии причиной. Я постоянно меняю коды и пробую другие свойства. Я решил проблему на самом деле, определив для FitchType.Eager, FetchType.SUBSELECT' и 'CacheConcurrencyStrategy.READ_WRITE' для обоих отношений, однако, это не лучшая конфигурация для нашего проекта. Теперь я хочу настроить отношение withtout 'FetchType.Eager'. – efirat

+0

@kirlisakal Вы попробовали решение, которое я упомянул, это сработало? – sunny

+0

На самом деле, теперь дело другое. Два из них вызывают ошибку при попытке опрокинуть класс 'Product'. В конце концов, я должен добавить или удалить «Цена» с «PriceDao». В этом случае проблема заключается в кеше.Я решил это, обновив кеш, когда я получу список «ProductPrice». – efirat

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