我想创建和删除 ProductPrice 之一, 更新工作正常,但其他人提供异常
产品类别
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>();
}
PRODUCTPRICE CLASS
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,我找不到有关这种情况的文档。我认为Map列出缓存会导致此错误。任何准备充分的文档建议也会得到批准。
答案 0 :(得分:0)
我假设在调用removeProductPrice()
之前你打开一个会话并开始一个交易。
在removeProductPrice()
方法中,通过执行get()将productPrice对象加载到持久性上下文。像,
ProductPrice price = productPriceDao.get(price.getPriceId());
// Then your logic to delete.
我怀疑传递给ProductPrice
方法的removeProductPrice()
对象不存在于会话的持久化上下文中。
是否可以发布完整的堆栈跟踪,显示导致异常的确切行。
答案 1 :(得分:0)
我找到的最后一个解决方案是;
真正的问题是同一个对象是在两个不同的列表缓存中。因此,当您更改其中一个时,它会根据您选择的FetchType方法导致错误。
如果您将FetchTypes定义为 FetchType.Eager , FetchType.SUBSELECT 和 CacheConcurrencyStrategy.READ_WRITE ,则可以通过更改两个对象来轻松实现缓存的一面!即你要删除其中一个价格,你应该从productPriceMap
&amp; 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 ON SERVICE
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);
}