本片博文整理关于Hibernate中级联策略cascade和它导致的异常:

Exception in thread "main" org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: com.mao.Address

关于这个异常应该是Hibernate初学者经常遇到的,导致该异常的原因就是:你的对象引用了一个未保存的瞬态实例,换句话讲就是:因为主表的记录不曾插入,所以参照该记录的从表记录也就无法插入

举个例子 咱们有两个表

表一 person_inf(从表)

结构:person_id(主键)    person_name    address_id(外键)

表二 address_inf(主表)

结构:address_id(主键)   address_detail

如果从表的记录(address_detail)都没持久化,还处于瞬态,你在主表person_inf中就引用了从表信息,从表记录自然也不会插入,而且就会报该错。

下面是具体一个OneToOne实例

1:Person.java

import java.util.*;

import javax.persistence.*;
@Entity
@Table(name="person_inf")
public class Person
{
// 标识属性
@Id @Column(name="person_id")
@GeneratedValue(strategy=GenerationType.IDENTITY)
private Integer id;
private String name;
private int age;
// 定义该Person实体关联的Address实体
@OneToOne(targetEntity=Address.class,cascade=CascadeType.ALL)
// 映射名为address_id的外键列,参照关联实体对应表的addres_id主键列
@JoinColumn(name="address_id"
, referencedColumnName="address_id" , unique=true)
private Address address;
//省略所有set get方法
}

注意上面代码中@OneToOne(cascade=CascadeType.All)这条,它就代表着将所有的持久化操作都级联到关联体中,意思就是系统会自动级联插入主表记录(address_inf表),再插入从表记录(person_inf),而不用担心该关联体是否已经保存为持久化状态

2:关联体Address.java

import java.util.ArrayList;
import java.util.List; import javax.persistence.*; @Entity
@Table(name="address_inf")
public class Address { @Id
@Column(name="address_id")
@GeneratedValue(strategy=GenerationType.IDENTITY)
private int addressId;
private String addressDetail;
public Address() { }
public Address(String addressDetail) {
this.addressDetail = addressDetail;
}
//省略set get方法

3:主程序PersonManager.java 这里只贴出部分添加数据代码

                Person person=new Person();
person.setName("VipMao");
person.setAge(24);
//创建一个瞬态 的Adress对象
Address address=new Address("山东曲阜");
//设置Person和Adress之间的关联关系
person.setAddress(address);
//persist方法并不是立刻将标识符填入到实例化中 这是与save方法的区别
session.persist(person);
tx.commit();

代码可以看出,我们并没有将address对象保存为持久化就直接通过session.persist(person)映射到person_inf数据表中了,这是因为我们前面设置了@OneToOne(cascade=CascadeType.All),这就说明当程序执行到session.persist(person)的时候,会先执行插入address_inf表记录,再执行插入person_inf表记录,从打印的SQL语句也可以看出:

这里也建议大家在学习Hibernate时把show_sql 设置成true 这样你就会清楚的看见程序先执行了什么后干了什么。

这就是级联操作。如果将@OneToOne(cascade=CascadeType.All)去掉,就没法通过级联插入address表数据,就会报错:Exception in thread "main" org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: com.mao.Address

另一种解决方式就是将程序改成如下

              Person p = new Person();
// 设置Person的name为crazyit字符串
p.setName("VipMao");
p.setAge(24);
// 创建一个瞬态的Address对象
Address a = new Address("山东曲阜");
// 通过Person对象建立它自己与Address实体的关联关系
p.setAddress(a);
// 先持久化Address对象(对应为插入主表记录)
session.persist(a);
// 再持久化Person对象(对应为插入从表记录)
session.save(p);
tx.commit();

在将数据插入之前就将他持久化。

4:运行结果

可以发现无论通过cascade=CascadeType.All级联方式还是通过手动先保存持久化都可以实现

总结:

Exception in thread "main" org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: com.mao.Address

导致原因:

你的对象引用了一个未保存的瞬态实例,换句话讲就是:因为主表的记录不曾插入,所以参照该记录的从表记录也就无法插入

解决方案:

1:通过cascade=CascadeType.All将Hibernate的所有持久化操作都级联到关联实体

2:将你需要插入的数据先持久化,再映射到相应的表中。

帖子来源于:https://blog.csdn.net/VipMao/article/details/51378237

ERROR org.hibernate.internal.SessionImpl - HHH000346: Error during managed flush [object references an unsaved transient instance - save the transient instance before flushing: cn.itcast.domain.Custom的更多相关文章

  1. org.hibernate.AnnotationException: No identifier specified for entity: cn.itcast.domain.Counter

    因为我的hibernate映射表没有主键所以报这个错. 解决方案是: 1.创建一个主键 2.hibernate处理无主键的表的映射问题,其实很简单,就是把一条记录看成一个主键,即组合主键<com ...

  2. 三大框架常遇的错误:hibernate : object references an unsaved transient instance

    hibernate : object references an unsaved transient instance 该错误是操作顺序的问题,比如: save或update顺序问题---比方学生表和 ...

  3. Exception in thread "main" org.hibernate.TransientObjectException: object references an unsaved tran

    今天在使用一对多,多对一保存数据的时候出现了这个错误 Hibernate错误: Exception in thread "main" org.hibernate.Transient ...

  4. Hibernate的一个问题object references an unsaved transient instance - save the transi5

    1 我做了一对多和多对一的双向关联关系,在User这一方@ManyToOne已经设置了级联Cascade,这样在测试程序中保存User时,Group也应该自动保存,为什么会抛出以下的异常: (我是按着 ...

  5. hibernate 对象状态异常:object references an unsaved transient instance - save the transient instance before flushing

    我的问题出在,删除的对象对应的表中有一个外键,关联着另外一个表,可是另外一个表中没有数据,所以报了这个错误. 参考http://www.cnblogs.com/onlywujun/archive/20 ...

  6. hibernate : object references an unsaved transient instance 问题

    save顺序问题---比如学生表和班级表..学生表里有班级ID的外键.一对多的关系. 你save的时候应该先save班级,再save学生..否则学生的外键没有对应的值,引发异常

  7. 关于Error during managed flush [Batch update returned unexpected row count from update [0]; actual row count: 0; expected: 1]错误

    控制台报错: 08:07:09.293 [http-bio-8080-exec-2] ERROR org.hibernate.internal.SessionImpl - HHH000346: Err ...

  8. ERROR [org.hibernate.engine.jdbc.spi.SqlExceptionHelper] - Data truncation: Incorrect datetime value: '' for column 'pubdate' at row 1

    之前的Connector/J版本是:mysql-connector-java-5.0.4-bin.jar 后来换成mysql-connector-java-5.1.45-bin.jar,问题解决 20 ...

  9. 报错HTTP Status 500 - HHH000142: Javassist Enhancement failed: cn.itcast.entity.Customer; nested exception is org.hibernate.HibernateException: HHH000142: Javassist Enhancement failed: cn.itcast.entity.

    报错 type Exception report message HHH000142: Javassist Enhancement failed: cn.itcast.entity.Customer; ...

随机推荐

  1. 上下文管理协议with open as

    我们知道在操作文件对象的时候可以这么写 with open('a.txt') as f: '代码块' 上述叫做上下文管理协议,即with语句,为了让一个对象兼容with语句,必须在这个对象的类中声明_ ...

  2. ENQ: KO - FAST OBJECT CHECKPOINT tips

    ENQ: KO - FAST OBJECT CHECKPOINT tips Question: What does the wait event ENQ: KO - FAST OBJECT CHECK ...

  3. P2251 质量检测--洛谷luogu

    传送门 题目描述 为了检测生产流水线上总共N件产品的质量,我们首先给每一件产品打一个分数A表示其品质,然后统计前M件产品中质量最差的产品的分值Q[m] = min{A1, A2, ... Am},以及 ...

  4. Scarpy 起始url 自定义代理 自定义去重规则

    - start_urls - 内部原理 """ scrapy引擎来爬虫中去起始的URL: 1. 调用start_requests并获取返回值 2. v = iter(返回 ...

  5. 3-STM32物联网开发WIFI(ESP8266)+GPRS(Air202)系统方案数据篇(安装配置数据库,使用Navicat for MySQL和手机APP 连接测试)

    2-STM32物联网开发WIFI(ESP8266)+GPRS(Air202)系统方案数据篇(数据库简单说明) https://www.mysql.com/ 咱用安装版的 我把自己下载的放在了这里 现在 ...

  6. Wireshark抓包分析TCP 3次握手、4次挥手过程

    Wireshark简介 更多有关Wireshark的教程.软件下载等,请见:http://www.52im.net/thread-259-1-1.html,本文只作简要介绍. 1Wireshark 是 ...

  7. Android Studio 2.2新增布局——ConstraintLayout完全解析

    ,但是Button并没有紧贴到布局的最右侧,这是为什么呢?实际上,Android Studio给控件的每个方向上的约束都默认添加了一个16dp的间距,从Inspector上面也可以明显地看出来这些间距 ...

  8. 简单的自定义ViewGroup

    自定义ViewGroup需要重写onMeasure, onLayout等方法.下面是一个实例,4个View分别显示在四个角. public class MyGroup extends ViewGrou ...

  9. Java性能优化之使用NIO提升性能(Buffer和Channel)

    在软件系统中,由于IO的速度要比内存慢,因此,I/O读写在很多场合都会成为系统的瓶颈.提升I/O速度,对提升系统整体性能有着很大的好处. 在Java的标准I/O中,提供了基于流的I/O实现,即Inpu ...

  10. 能递归检查DataAnnotations的验证函数

    有时在Command和DTO之间层次比较多,写了个验证Command的函数,能实现递归验证. 比如下面这些有层级关系的class定义,能通过一句代码来进行验证: class A { [Required ...