级联保存或更新CASCADE

级联保存或更新:

  作用就是:保存一方的数据的时候,会把关联的对象也同时保存。

级联保存或更新的配置:

    属性名:cascade

        属性值:

            1.none:所有情况下均不进行关联操作。(默认值)

            2.save-update:在执行save/update/saveOrUpdate时进行关联操作

            3.delete:在执行delete时进行关联操作

            4.all-delete-orphan:当一个节点在对象图中成为孤儿节点时,删除该节点

            5.all:所有情况下均进行关联操作,即save-update和delete(但是不推荐,避免删除后级联删除最后导致莫名其妙少了很多数据)

先贴上一段代码:

    这段代码是上一章的代码,作用是创建新用户并且创建两个订单添加到该客户中。

    新创建的对象都是瞬时状态,我们保存到数据库需要将对象进行持久化操作。

    这里发现,最后持久化对象用了三行代码。

     session.save(cst); session.save(od); session.save(od1);

    又保存客户,又保存两个订单,感觉代码有点多。但是不执行后两个行代码又不行,瞬时状态的怎么可以!

    所以我们就得设置级联操作了,这样就可以保存某一方的同时,自动保存或更新级联的对象。

/**
* 创建新用户并且创建两个订单添加到该客户中
*/
@Test
public void fun1(){
Session session = HibernateUtils.getSession();
session.getTransaction().begin(); try {
//新建用户 瞬时状态
Customer cst = new Customer();
cst.setCust_id(1);
cst.setCust_name("台用胜");
cst.setCust_gender("男");
cst.setCust_age(24);
cst.setCust_phone("18736549531"); //新建订单 瞬时状态
Order od = new Order();
od.setOrder_id(UUID.randomUUID().toString());
od.setDetail_id(UUID.randomUUID().toString()); Order od1 = new Order();
od1.setOrder_id(UUID.randomUUID().toString());
od1.setDetail_id(UUID.randomUUID().toString()); //表达客户和订单的关系
cst.getOds().add(od);
cst.getOds().add(od1);
//表达订单和客户的关系
od.setCst(cst);
od1.setCst(cst);
//持久化用户和订单
session.save(cst);
session.save(od);
session.save(od1);
} catch (Exception e) {
session.getTransaction().rollback();
e.printStackTrace();
} session.getTransaction().commit();
}

级联保存或更新的操作:

  这里有客户对订单的关系,上述中,给客户添加订单需要三行代码。

  这三行代码中, 如果我们认为客户方是“主控方”那么后面的两行代码我们就可以省略,如果我们认为订单方是“主控方”那么第一行的代码就可以省略。具体看代码

  那我就举一个例子,选择客户方是“主控方”,

  1.配置Customer.hbm.xml(在配置的时候添加cascade="save-update")

<?xml version = "1.0" encoding = "UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="deep.domain">
<class name="Customer" table="customera">
<id name="cust_id" column = "cust_id">
<generator class="native"></generator>
</id> <property name="cust_name" column = "cust_name"></property>
<property name="cust_gender" column = "cust_gender"></property>
<property name="cust_age" column = "cust_age"></property>
<property name="cust_phone" column = "cust_phone"></property> <!-- 配置一对多属性 -->
<set name="ods" cascade="save-update">
<key column="cust_order_id" ></key>
<one-to-many class="Order"/>
</set> </class> </hibernate-mapping>

2.随后将上面粘贴的java代码进行修改(我们会发现,少了session.save(od)和session.save(od1)),但是效果是一样的

/**
* 级联保存或更新
* 创建新用户并且创建两个订单添加到该客户中
*/
@Test
public void fun2(){
Session session = HibernateUtils.getSession();
session.getTransaction().begin(); try {
//新建用户 瞬时状态
Customer cst = new Customer();
cst.setCust_id(1);
cst.setCust_name("台用胜");
cst.setCust_gender("男");
cst.setCust_age(24);
cst.setCust_phone("18736549531"); //新建订单 瞬时状态
Order od = new Order();
od.setDetail_id(UUID.randomUUID().toString()); Order od1 = new Order();
od1.setDetail_id(UUID.randomUUID().toString()); //表达客户和订单的关系
cst.getOds().add(od);
cst.getOds().add(od1);
//表达订单和客户的关系
od.setCst(cst);
od1.setCst(cst); //持久化用户和订单
session.save(cst);
} catch (Exception e) {
session.getTransaction().rollback();
e.printStackTrace();
} session.getTransaction().commit();
}

同样,如果我们认为订单方是“主控方”,那么就只要这样配置

<!-- 配置多对一属性 -->
<many-to-one name="cst" class="Customer" column="cust_order_id" cascade="save-update" />

随后的java代码是:(获取主键值为 6的客户,并新建两个订单添加到该客户中)

/**
* 级联保存或更新
* 获取用户并且创建两个订单添加到该客户中
*/
@Test
public void fun3(){
Session session = HibernateUtils.getSession();
session.getTransaction().begin(); try {
//获取主键值为6的客户 瞬时状态
Customer cst = session.get(Customer.class, 6); //新建订单 瞬时状态
Order od = new Order();
od.setDetail_id(UUID.randomUUID().toString()); Order od1 = new Order();
od1.setDetail_id(UUID.randomUUID().toString()); //表达客户和订单的关系
cst.getOds().add(od);
cst.getOds().add(od1);
//表达订单和客户的关系
od.setCst(cst);
od1.setCst(cst); //持久化用户和订单
session.save(od);
session.save(od1);
} catch (Exception e) {
session.getTransaction().rollback();
e.printStackTrace();
} session.getTransaction().commit();
}

刚刚上面的是两种单一方向,也可以认为订单方和客户方都是“主控方”,方法自然很简单,就是在两边都加上cascade="save-update"啦~

到这里cascade概念基本可以了,我也算是有点理解了吧,这样确实方便很多,少了代码量,也比较人性化。

问题:我的订单表中的主键这是的是uuid,在配置文件中设置了主键自增策略是uuid,在创建新订单的时候,我有一个订单.setId的动作,并且手动生成了uuid。 在我没有级联操作的时候,能够正常添加订单,但是级联操作后就会报错,java代码和报错代码如下(我认为客户方是“主控方”)

错误明细:

 十一月 18, 2018 4:31:07 下午 org.hibernate.internal.SessionImpl$5 mapManagedFlushFailure
ERROR: HHH000346: Error during managed flush [Batch update returned unexpected row count from update [0]; actual row count: 0; expected: 1]

百度查了也没搞懂是怎么回事,想了有一会儿,然后报错,看到错误来源sql语句update的第一个参数,我就看到了我java中,然后猜测是主键策略方面的问题,我就尝试把那一行代码删除,发现可以运行,但是不知道为什么。如果有大佬知道希望能指点一二。。谢谢啦~

Hibernate入门(八)级联保存或更新(含问题在末尾,求大佬指点..)的更多相关文章

  1. Hibernate入门(九)级联删除

    Hibernate级联删除 上一篇文章学习了级联保存和更新,这个级联删除应该很好理解的.一样的道理,删除一方,同时删除有关联的一方. https://www.cnblogs.com/deepSleep ...

  2. hibernate级联保存,更新个人遇到的问题

    在级联更新的时候,数据库中的数据是增加的,只是外键不存在,导致这样的问题产生的原因是,字表主键ID没有添加到集合中,导致Hibernate找不到子项而执行更新.

  3. hibernate 一对多 级联 保存修改 删除

    一对多,一端设置: <set name="TWorkorderHistories" inverse="true" cascade="all&qu ...

  4. [原创]关于Hibernate中的级联操作以及懒加载

    Hibernate: 级联操作 一.简单的介绍 cascade和inverse (Employee – Department) Casade用来说明当对主对象进行某种操作时是否对其关联的从对象也作类似 ...

  5. (原创)Hibernate 使用过程中(尤其是多对多关联中的级联保存和级联删除)的注意事项(基于项目的总结)

    一.先上知识点: 1.hibernate多对多关联关系中最重要的参数是(基于配置文件xxx.hbm.xml文件形式): 1):inverse属性,如果设置inverse=“true”就代表让对方参与维 ...

  6. Hibernate中表与表之间的关联多对多,级联保存,级联删除

    第一步:创建两个实体类:用户和角色实体类,多对多关系,并让两个实体类之间互相关联: 用户实体类: package com.yinfu.entity; import java.util.HashSet; ...

  7. Hibernate中表与表之间的关联一对多,级联保存和级联删除

    1:Hibernate的一对多操作(重点) 一对多映射配置 第一步:创建两个实体类:客户和联系人(例)以客户为一,联系人为多: package com.yinfu.entity; public cla ...

  8. Hibernate的级联保存、级联删除

    级联操作: 属性:cascade 值:save-update(级联保存) delete(级联删除) all(级联保存+级联删除) 优点:虽然,不用级联操作也能解决问题.但是级联操作可以减少代码量,使得 ...

  9. Hibernate入门5持久化对象关系和批量处理技术

    Hibernate入门5持久化对象关系和批量处理技术 20131128 代码下载 链接: http://pan.baidu.com/s/1Ccuup 密码: vqlv 前言: 前面学习了Hiberna ...

随机推荐

  1. [转] Snapshotting with libvirt for qcow2 images

    http://kashyapc.com/2011/10/04/snapshotting-with-libvirt-for-qcow2-images/ Libvirt 0.9.6 was recentl ...

  2. QEMU KVM libvirt手册(2): monitor

    Administrating Virtual Machines with QEMU Monitor When QEMU is running, a monitor console is provide ...

  3. mvc网站迁移.net core记录

    接口return Json()时序列号小写的问题 在Startup.cs->ConfigureServices方法配置一下解决 public void ConfigureServices(ISe ...

  4. 第79节:Java中一些要点

    第79节:Java中一些要点 前言 一些知识点忘了没,可以通过一个点引出什么内容呢?做出自己的思维导图,看看自己到了哪一步了呢 内容 如果有人问jre,jdk,jvm是什么,你怎么回答呢? jre的英 ...

  5. OAuth2简易实战(一)-四种模式

    1. OAuth2简易实战(一)-四种模式 1.1. 授权码授权模式(Authorization code Grant) 1.1.1. 流程图 1.1.2. 授权服务器配置 配置授权服务器中 clie ...

  6. SpringMVC项目容易出现的BUG

    1.400错误:1.语义有误,当前请求无法被服务器理解.除非进行修改,否则客户端不应该重复提交这个请求. 2.请求参数有误. 你发送的请求有误,这个问题去页面提交的地方看. 如:你想删除一条数据,id ...

  7. 新年放大招:Github 私库免费了!

    据<Github 嫁入豪门>这篇文章刚好半年了,那时候栈长还表示对 Github 的期待,仅仅半年,现在就已经有了巨大改变. 微软果然是豪门,嫁入半年就已经开花结果了,免费私库已全面无限制 ...

  8. session的一些笔记

    HttpSession hs = request.getSession();//以键值对方式存储数据在session中hs.setAttribute("code", code);/ ...

  9. jquery click嵌套 事件重复注册 多次执行的问题解决

    jquery click事件中嵌套click会重复注册内部的click事件,导致重复执行. 比如 $(...).click(function(){   $(...).click(function(){ ...

  10. Mac下快速搭建PHP开发环境

    最近做了一个后端的项目,是用PHP+MySQL+Nginx做的,所以把搭建环境的方法简单总结一下. 备注: 物料:Apache/Nginx+PHP+MySQL+MAMP Mac OS 10.12.1 ...