本片博文整理关于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. Mybatis学习总结(八)——延迟加载

    一.什么是延迟加载 resultMap可以实现高级映射(使用association.collection实现一对一及一对多映射),association.collection具备延迟加载功能. 需求: ...

  2. leetcode 4:Median of Two Sorted Arrays

    public double FindMedianSortedArrays(int[] nums1, int[] nums2) { int t=nums1.Length+nums2.Length; in ...

  3. .Net外包篇:我是如何看待外包的

    前言 从工作至今,我在工作之余大大小小接了六次外包,不多不少,虽然没有为我带来很大收益,但也让我开拓了人脉,接触了不少知识,锻炼了全栈开发能力. 菜鸟时代 第一家客户(成功) 我接的第一个外包是为一家 ...

  4. React中嵌套组件与被嵌套组件的通信

    前言 在React项目的开发中经常会遇到这样一个场景:嵌套组件与被嵌套组件的通信. 比如Tab组件啊,或者下拉框组件. 场景 这里应用一个最简单的Tab组件来呈现这个场景. import React, ...

  5. SAI窗口无法移动

    昨天开SAI遇到了一个很奇怪的问题,改变了双屏的位置后SAI的窗口不能移动两边也有黑边,貌似是这样,标题栏只能进行上下改变窗口大小,不能移动窗体 问题是这样出现的:把任务栏解除锁定拖到侧边就会这样 解 ...

  6. 二十二:制作app的时候超出部分不能滑动

    给需要滑动的区域写以下样式(父级是浏览器) position: absolute; left: 0; right: 0; bottom: 0; top: 0; overflow-x: hidden; ...

  7. SQL Server 跨服务器查询

    select * from OPENDATASOURCE( 'SQLOLEDB', 'Data Source=10.10.10.10;User ID=sa;Password=123456'). [CF ...

  8. 关于R语言中dnorm,pnorm,qnorm,rnorm的用法

    dnorm,pnorm,qnorm,rnorm的表达式: 其中x和q是由数值型变量构成的向量,p是由概率构成的向量,n是随机产生的个数 mean是要计算正态分布的均值,缺省值为0,sd是计算正态分布的 ...

  9. Springboot通过cors解决跨域问题(解决spring security oath2的/oauth/token跨域问题)

    @Bean public CorsFilter corsFilter() { final UrlBasedCorsConfigurationSource source = new UrlBasedCo ...

  10. Of Study

    Bacon Reading maketh a full man; conference a ready man; and writing an exact man. And therefore, if ...