Java Hibernate JPA删除OneToMany关系和MapKeyJoinColumn关系对象
我想创建并删除ProductPrice中的一个, 更新工作正常,但其他人给出了例外 产品类别Java Hibernate JPA删除OneToMany关系和MapKeyJoinColumn关系对象,java,hibernate,caching,one-to-many,Java,Hibernate,Caching,One To Many,我想创建并删除ProductPrice中的一个, 更新工作正常,但其他人给出了例外 产品类别 public class Product extends GenericEntity { @OneToMany(fetch=FetchType.EAGER, mappedBy = "product", targetEntity = ProductPrice.class, cascade = {CascadeType.ALL}, orphanRemoval=true) @Fetch(Fet
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);
}
我没有完全获得MapKeyJoin列,也找不到关于这种情况的文档。我认为地图列表缓存导致了这个错误。任何准备好的文档建议都会得到批准。我假设在调用
removeProductPrice()
之前,您打开了一个会话并开始了一个事务
在removeProductPrice()
方法中,通过执行get()将productPrice对象加载到持久性上下文。像
我怀疑传递给removeProductPrice()
方法的ProductPrice
对象在会话的持久性上下文中不存在
你能发布完整的堆栈跟踪吗?它显示了导致异常的确切行。我找到的最后一个解决方案是 真正的问题是同一个对象位于两个不同的列表缓存中。所以,当您更改其中一个时,根据您选择的FetchType方法会导致错误 如果将FetchType定义为FetchType.Eager、FetchType.SUBSELECT和cacheconcurrencysttrategy.READ\u WRITE,则可以通过更改缓存两侧的对象轻松进行crud!i、 e.如果您想删除price中的一个,也应该将其从
productPriceMap
和productPrices
中删除。然后合并产品代码>它已经完成了
@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>();
@OneToMany(fetch=FetchType.EAGER,mappedBy=“product”,targetEntity=ProductPrice.class,cascade={CascadeType.ALL},orphanRemoving=true)
@Fetch(FetchMode.SUBSELECT)
@缓存(用法=cacheconcurrentystrategy.READ\u WRITE,region=“ncStandardElements”)
private List productPrices=new ArrayList();
@OneToMany(fetch=FetchType.EAGER,mappedBy=“product”,targetEntity=ProductPrice.class)
@Fetch(FetchMode.SUBSELECT)
@MapKeyJoinColumn(name=“CURRENCY\u ID”)
@缓存(用法=cacheconcurrentystrategy.READ\u WRITE,region=“ncStandardElements”)
私有映射productPriceMap=新HashMap();
在役积垢
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);
}
public void removeProductPrice(ProductPrice价格){
产品p=price.getProduct();
Map productPriceMap=p.getProductPriceMap();
productPriceMap.remove(价格);
标价=p.getProductPrices();
价格。删除(价格);
p、 设定产品价格(价格);
p、 移除ProductPriceMap(价格);
合并(p);
}
public void saveProductPrice(ProductPrice,布尔值isNew){
产品p=price.getProduct();
标价=p.getProductPrices();
如果(是新的){
价格。添加(价格);
}
否则{
int i=0;
对于(产品价格tp:价格){
if(tp.getId()==price.getId()){
价格。设定(i,价格);
打破
}
i++;
}
}
p、 设定产品价格(价格);
合并(p);
}
productDao.merge(p)代码>行原因错误。我不断地更改代码并尝试其他属性。实际上,我已经解决了这个问题,为这两个关系定义了FetchType.Eager、FetchType.SUBSELECT
和cacheconcurrencysttrategy.READ\u WRITE
,但是,这并不是我们项目的最佳配置。现在,我想配置关系wihtoutFetchType.Eager
@kirlisakal您尝试过我提到的解决方案了吗?实际上,现在情况不同了。当您试图在产品
类上进行crud时,两个关系会导致错误。毕竟,我必须从PriceDao
中添加或删除Price
。在这种情况下,问题在于缓存。当我得到ProductPrice
list时,我通过刷新缓存解决了这个问题。
@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>();
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);
}