关于hibernate的 No row with the given identifier exists

栏目: Hibernate · 发布时间: 6年前

内容简介:网上出现此问题大概原因有以下几种:但是我本地不是,我是多的一方数据不存在,废话不多先上代码:以上是实体类对应的为伪代码,接下来是业务操作:

网上出现此问题大概原因有以下几种:

  • 多对一配置中,一的一方数据不存在时报此异常
  • 双向关联的一方数据不存在时报此异常

但是我本地不是,我是多的一方数据不存在,废话不多先上代码:

// 伪代码
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高并发编程详解

Java高并发编程详解

汪文君 / 机械工业出版社 / 2018-6 / 89.00元

本书共分为四个部分:部分详细地介绍了Java多线程的基本用法和各个API的使用,并且着重介绍了线程与Java虚拟机内存之间的关系。第二部分由线程上下文类加载器方法引入,介绍为什么在线程中要有上下文类加载器的方法函数,从而掌握类在JVM的加载和初始化的整个过程。第三部分主要围绕着volatile关键字展开,在该部分中我们将会了解到现代CPU的架构以及Java的内存模型(JMM)。后一部分,主要站在架......一起来看看 《Java高并发编程详解》 这本书的介绍吧!

HTML 压缩/解压工具
HTML 压缩/解压工具

在线压缩/解压 HTML 代码

随机密码生成器
随机密码生成器

多种字符组合密码

XML 在线格式化
XML 在线格式化

在线 XML 格式化压缩工具