项目记事Hibernate-1:调用 saveOrUpdate() 方法出错

Posted Gerrard_Feng

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了项目记事Hibernate-1:调用 saveOrUpdate() 方法出错相关的知识,希望对你有一定的参考价值。

Hibernate 版本:3.3.1

 

 

背景:

后端编辑一个对象,该对象(ProductDO)下,有一个另一个自定义对象(ProductLiabilityDO)的 OneToMany 关系,如下:

@OneToMany(targetEntity = ProductLiabilityDO.class, mappedBy = "product", cascade = CascadeType.ALL)
private List<ProductLiabilityDO> liabilities = ListUtil.newArrayList();

而在 ProductLiabilityDO 对象中,又持有对 ProductDO 对象的 ManyToOne 关系,如下:

@ManyToOne(targetEntity = ProductDO.class, fetch = FetchType.LAZY)
@JoinColumn(name = "productId")
private ProductDO product;

在对 ProductDO 对象进行 update 操作的时候(ProductLiabilityDO 的列表有增有减)报错,信息如下:

 

deleted object would be re-saved by cascade (remove deleted object from associations)

 

 

错误分析1:

如提示所说的,被删除的内容,由于级联关系的配置,会被重新保存。

 

 

解决方案1:

在 OneToMany 的一方,增加 Hiberbate 的 @Cascade 注解,这个注解有一个孤儿属性,可以保证被删除的内容,不会由于级联关系,被重新保存。

@OneToMany(targetEntity = ProductLiabilityDO.class, mappedBy = "product", cascade = CascadeType.ALL)
@Cascade(org.hibernate.annotations.CascadeType.DELETE_ORPHAN)
private List<ProductLiabilityDO> liabilities = ListUtil.newArrayList();

 

 

新的问题:

在执行完成以上步骤之后,发现了新的问题:

 

org.hibernate.HibernateException:
]A collection with cascade="all-delete-orphan" was no longer referenced by the owning entity instance: com.XXXX.pms.actual.model.ProductDO.liabilities

 

 

出错代码位置:

productDO.setLiabilities(transferLiabilities(vo.getLiabilities(), productDO, productLiabilityAssignments));

 

 

错误分析2:

原来 ProductDO 的此属性,已经持有对于一个 ProductLiabilityDO 列表的引用,直接用另外一个列表的引用,替代这个引用,在最后调用 saveOrUpdate() 方法时报错。

 

 

解决方案2:

将原来的列表清空,然后将入参给予的列表加入空列表,规避问题。

由于调用的地方过多,在所有增加 @Cascade 注解的属性的 set() 方法全部重写,防止以后再次误操作。

public void setLiabilities(List<ProductLiabilityDO> liabilities) {
    if (this.liabilities == liabilities) {
        return;
    }
    this.liabilities.clear();
    this.liabilities.addAll(liabilities);
}

 

 

Over,问题解决!

 


以上是关于项目记事Hibernate-1:调用 saveOrUpdate() 方法出错的主要内容,如果未能解决你的问题,请参考以下文章

项目:简单记事本

《记事本》第1节:记事本项目简介

python调用pywin32打开记事本只打开了notepad.exe进程没有打开记事本编辑窗口?

Electron 调用系统工具记事本计算器等

C#调用记事本并填写内容

记事本项目记录