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. hibernate save,update,saveorupdate方法有什么区别

    save肯定是添加的时候用,update修改时候用,saveorupdate是添加或修改,如果真是这样save和update的存在就没意义了,我们直接saveorupdate就行了. save在添加用 ...

  2. c# js调用AjaxPro方法出错解析

    公司的项目的框架中有一部分用到了AjaxPro这个方法,看到这个方法的我一脸懵逼,老老实实去百度了一下. AjaxPro是.NET平台下的一个回调式AJAX框架,使用简单,功能强大.顾名思义ajax, ...

  3. 线程中调用service方法出错

    public class PnFileTGIComputeThread implements Runnable { @Resource private AppUsedService appUsedSe ...

  4. Hibernate中对象的三种状态以及Session类中saveOrUpdate方法与merge方法的区别

    首先,用一张图说明一个对象,在Hibernate中,在调用了不同方法之后对象所处的不同状态 在Hibernate中,一个对象的状态可以被分为如图所示的三种 Transient:瞬时对象,该对象在数据库 ...

  5. Hibernate(5)session的方法

    1. Session缓存 Session缓存(Hibernate一级缓存),在 Session 接口的实现中包含一系列的 Java 集合, 这些 Java 集合构成了 Session 缓存.只要 Se ...

  6. VS2010 F5调试时出现:“ 尝试运行项目时出错:未捕获通过反射调用的方法引发的异常”解决

    VS2010 F5调试时出现 尝试运行项目时出错:未捕获通过反射调用的方法引发的异常 两个解决方法:1) 打开项目属性,选择调试选项卡,将“启用非托管代码调试”一项钩上.2) 打开项目属性,选择调试选 ...

  7. [原创]java WEB学习笔记79:Hibernate学习之路--- 四种对象的状态,session核心方法:save()方法,persist()方法,get() 和 load() 方法,update()方法,saveOrUpdate() 方法,merge() 方法,delete() 方法,evict(),hibernate 调用存储过程,hibernate 与 触发器协同工作

    本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...

  8. Hibernate 的saveOrUpdate方法(转)

    hibernate提供了saveOrUpdate的方法来进行数据库的操作.hibernate会根据对象的状态决定是insert还是update,其根本是通过xml文件中unsaved-value来确定 ...

  9. Hibernate session.saveOrUpdate()方法

    saveOrUpdate()方法同时包含了save()与update()方法的功能, 如果传入的参数是临时对象,就调用save()方法: 如果传入的参数是游离对象,就调用update()方法: 如果传 ...

随机推荐

  1. 51nod 1572 宝岛地图

    题目来源: CodeForces 基准时间限制:1 秒 空间限制:131072 KB 分值: 20 难度:3级算法题 勇敢的水手们到达了一个小岛,在这个小岛上,曾经有海盗在这里埋下了一些宝藏.然而,我 ...

  2. Sequence II

    6990: Sequence II 时间限制: 3 Sec  内存限制: 128 MB提交: 206  解决: 23[提交][状态][讨论版][命题人:admin] 题目描述 We define an ...

  3. Mac格式化fat32格式

    好的,格式化硬盘可以使用电脑内置的磁盘工具来格式. 在 LaunchPad 中的 实用工具 或 其它 找到 磁盘工具 打开磁盘工具后,找到你的移动硬盘. (这里以我的希捷移动盘来示例) 非常容易找到, ...

  4. javascript 完整知识点整理

    by 蔡舒啸 目录 一 5种基本类型 typeof 关键字 三种强制类型转换 日期 二 if语句for语句whiledo-whileswitch-case 比较运算符 逻辑运算符 if for语句 w ...

  5. LEETCODE60——第K个排列

    class Solution { public: string getPermutation(int n, int k) { '); vector<bool> flag(n, false) ...

  6. JDBC操作数据库的详细步骤

    1.注册驱动 告知JVM使用的是哪一个数据库的驱动 2.创建连接 使用JDBC中的类,完成对MySQL数据库的连接 3. 得到执行sql语句的Statement对象 通过连接对象获取对SQL语句的执行 ...

  7. redis cluster 配置

    #服务器192.168.56.111 192.168.56.112 192.168.56.113 计划1主2从   192.168.56.111 192.168.56.112 192.168.56.1 ...

  8. 【Linux】开放指定端口设置

    这里以开放tomcat的8080端口为例 1.开放Linux的8080端口 vi /etc/sysconfig/iptables 进入编辑页面,在指定位置新增以下配置 -A INPUT -m stat ...

  9. 树莓派编译ncnn

    1.从github上下载ncnn git clone --recursive https://github.com/Tencent/ncnn 2.在ncnn根目录下创建build目录,安装cmake编 ...

  10. vue创建路由,axios前后台交互,element-ui配置使用,django contentType组件

    vue中创建路由 每一个vue组件都有三部分组成 template:放html代码 script:放js相关 style:放css相关 vue中创建路由 1.先创建组件 Course.vue 2.ro ...