内容简介:网上出现此问题大概原因有以下几种:但是我本地不是,我是多的一方数据不存在,废话不多先上代码:以上是实体类对应的为伪代码,接下来是业务操作:
网上出现此问题大概原因有以下几种:
- 多对一配置中,一的一方数据不存在时报此异常
- 双向关联的一方数据不存在时报此异常
但是我本地不是,我是多的一方数据不存在,废话不多先上代码:
// 伪代码 class Class{ @Id Long id; @OneToMany(cascade = CascadeType.DETACH,mappedBy = "clazz") List<Student> students; public Class(Map<String,Object> param){ // 构建新的对象 Class newClazz = new Class(); newClazz.setId((Long)param.get("id")); // 构建新的学生对象 List<Map<String,Object>> studentMaps = param.get("students"); students = new ArraryList(); studentMaps.forEach(map -> { Student st = new Student(); st.setId((Long)map.get("id")); students.add(st); }) } } class Student{ @Id Long id; @ManyToOne(cascade = CascadeType.DETACH) @JoinColumn(name="class_id") Class clazz; } 复制代码
以上是实体类对应的为伪代码,接下来是业务操作:
class ClassManagerImpl implements IClassManager{ void saveOrUpdate(Map<String,Object> params){ Class newClass = new Class(params); Class oldClass = classDao.get(newClass.getId()); if(oldClass!=null){ newClass.setCreateDate(oldClass.getCreateDate()); } classDao.saveOrUpdate(newClass); } } class ClassDaoImpl implements IClassDao{ void saveOrUpdate(Class class){ try { this.hibernateTemplate.saveOrUpdate(class); } catch (DuplicateKeyException | NonUniqueObjectException e) { // 此处merge报出以上bug this.hibernateTemplate.merge(obj); } } } 复制代码
以上的代码,在出现以下这种情况:
Class已存在,但是他关联的Student对象不存在
会报两个错:
- A different object with the same identifier value was already associated with the session
- No row with the given identifier exists
出现第一个问题是由于调用saveOrUpdate()时由于我们调用get方法时已查询过一次Class对象,但是我们更新时又是创建的新对象,所以会报错。
出现第二个问题的原因是因为我们捕获了第一个异常:NonUniqueObjectException,然后调用merge()方法,merge方法用于合并属性,当我们有一对多等关联配置时,他会去数据库查询相应的数据来进行数据合并,如果关联数据不存在就会出错。
举例:
id为1的Class 存在数据库中,此处数据库中还没有Student数据。我们通过业务更新ID为1的Class,同时新增一个Student对象。此时就会报错
解决办法为增加not-found配置:
注解方式:
class Class{ @Id Long id; @OneToMany(cascade = CascadeType.DETACH,mappedBy = "clazz") @NotFound(action= NotFoundAction.IGNORE) List<Student> students; } 复制代码
XML配置方式:
<class name="Class" table="class"> <id column="id" name="id" type="java.lang.Long"><generator class="assigned" /></id> <bag name="students" cascade="none"> <key>class_id</key> <one-to-many not-found="ignore" class="Student" /> </bag> </class> 复制代码
该参数默认为EXCEPTION,即找不到的话就会抛出异常。
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Java高并发编程详解
汪文君 / 机械工业出版社 / 2018-6 / 89.00元
本书共分为四个部分:部分详细地介绍了Java多线程的基本用法和各个API的使用,并且着重介绍了线程与Java虚拟机内存之间的关系。第二部分由线程上下文类加载器方法引入,介绍为什么在线程中要有上下文类加载器的方法函数,从而掌握类在JVM的加载和初始化的整个过程。第三部分主要围绕着volatile关键字展开,在该部分中我们将会了解到现代CPU的架构以及Java的内存模型(JMM)。后一部分,主要站在架......一起来看看 《Java高并发编程详解》 这本书的介绍吧!