在Hibernate中正确实现关联关系中的级联操作(cascading)

关系数据库系统本身就比较复杂,加上Hibernate的O/R映射层,复杂度加重了,很容易出现问题,本人将最近遇到的问题和解决方法做一个总结,整理在下面的一系列文章中

正确理解Hibernate的聚合类型(collection)的使用

在Hibernate中正确实现关联关系中的级联操作(cascading)

在Hibernate框架中编写持久对象类实现外键关联的几点注意事项

本文是第二篇,讲解在one-to-many(一对多)和many-to-one(多对一)关联关系中的cascade特性的声明方法。在使用过程中最关键点是:脑子中要有一张持久对象关系树及其状态图(状态分别是:Transient, Persistent, Detached),存在对象间关联关系时,如果使用了级联操作特性,要找到树的根对象(所以要用树,而不是图),从根往下级联操作,只做单方向的级联。

我们再次使用第一篇的例子,为了反映两者的关联关系,为User类我们声明如下一对多关系

<class name="User" table="USER">
...
<set name="preferences"
cascade="all,delete-orphan"
inverse="true">
<key column="USER_ID" not-null="true"/>
<one-to-many class="Preference"/>
</set>
...
</class>

而为Preference类声明如下多对一关系

<class name="Preference" table="PREFERENCE">
...
<many-to-one name="user" column="USER_ID" not-null="true"
foreign-key="ALLPREFERENCES" class="User"/>
...
</class>

由上可见,在User和Preference的关系树中,User是根(root),另外还可以看到为Preference声明了一个not- null的外键。在理清了级联的顺序关系后,后续的持久化操作可以只对User进行即可,Preference的持久化由级联操作完成。

根据Hibernate的原理和官方建议,应该采用以下持久化方法:

session.save():用于将Transient状态的对象及其级联对象持久化(即在该session中,处于persistent状态),例如,创建新对象及其关联。

session.flush()或者事务提交(commit)操作:用于将处于presistent状态的对象修改的持久化,例如,从数据库将一个关联树调到Hibernate中,修改后再次入库。

session.update(), session.saveOrUpdate(), session.merge():一般只用于处于detached状态的对象修改后进行的持久化操作(这是Hibernate的一个重要特色,可以很好的处理业务层面的事务(transaction)跟数据库层面的事务的配合问题),当然,这些方法用于上一种情况也没有错

session.delete():删除对象

做了上述实现后并不能保证关联关系的级联操作的正确执行,进一步分析参见后续文章。

在实践中很容易触发以下异常:

org.hibernate.ObjectDeletedException: deleted object would be re-saved by cascade (remove deleted object from associations): xxx

这主要是理不清级联关系造成的,按照本文和下一文介绍的方法可以排除。

还有一个异常:

Cannot delete or update a parent row: a foreign key constraint fails ([外键的定义])

其解决方法也是一样的。

时间: 2024-10-03 11:07:09

在Hibernate中正确实现关联关系中的级联操作(cascading)的相关文章

sql2000数据库-如何解决在iReport 的 Preview 中正确显示SQL2000 数据库中的中文?

问题描述 如何解决在iReport 的 Preview 中正确显示SQL2000 数据库中的中文? 我是新手,问题如下: 用iReport 5.1.0,只要不是从数据库中取出的中文在iReport 的Preview 均能正常显示,但用SELECT 从SQL2000 读取含有中文的字段数据,在iReport 的 Preview 中显示的是乱码,更不用说再生成PDF 是PDF中中文部分是乱码了,而如果数据库改为SQL 2005 ,则含有中文的字段一切正常.问题:如何解决在iReport 的 Prev

java-Hibernate中的1-N关联关系

问题描述 Hibernate中的1-N关联关系 在Hibernate创建1-N的关联关系,比如系部和课程的1-N关联.创建之后新建一个课程时必须要传入一个系部的对象.怎样才能不创建系部的对象,直接添加课程信息.

设计-关于hibernate查询的和开发中的一些疑问

问题描述 关于hibernate查询的和开发中的一些疑问 我在开发的过程中遇到一些疑问,希望各大牛帮我解答下. 环境介绍: 假设现在有2个表 表名:category(文章分类) 字段: id 主键 name 文章分类中文名 desc 描述 表名:article(文章列表) 字段: id 主键 categoryid 分类id title 文章标题 content 内容 因为用的是hibernate, 上面两个表对应的PO分别是CategoryPO , ArticlePO.没有配置外键映射. 现在要

【spring】一般情况下,我们一般建议在一对多双向关联关系中,将一方的inverse属性设置为true

一般情况下,我们一般建议在一对多双向关联关系中,将一方的inverse属性设置为true

请教各位朋友,Hibernate 能不能对oracle中视图的数据进行删除。目前只能查询

问题描述 请教各位朋友,Hibernate能不能对oracle中视图的数据进行删除.目前只能查询 解决方案 解决方案二:据我所知,视图中不能进行数据删除视图只是数据的映射吧,如果需要删除,只能操作源表请高手解答..解决方案三:不能,视图时不能修改的,如果你想修改视图就得建立触发器去操作.解决方案四:楼上都回答了啊解决方案五:谢谢各位的解答

分页-Hibernate中多对多关系中给用户赋予权限遇到的问题

问题描述 Hibernate中多对多关系中给用户赋予权限遇到的问题 我的问题是这样的 我有一个用户表 elec_user 一个角色表 elec_role 一个用户表和角色表之间联系的中间表 elec_user_role 我在jsp页面中给相应的角色赋予角色 但是由于考虑到角色太多,就给显示角色信息的table使用了分页 但是最后我给角色勾选了分配角色后,由于点了分页的原因,之前的数据又没有了,这又没有 好的解决办法呢?? 我的想法就是在jsp页面中搞个隐藏域,当每次勾选了就给隐藏域的值加上每个角

MVC3不能正确识别JSON中的Enum枚举值

原文:MVC3不能正确识别JSON中的Enum枚举值 一.背景 在MVC3项目里,如果Action的参数中有Enum枚举作为对象属性的话,使用POST方法提交过来的JSON数据中的枚举值却无法正确被识别对应的枚举值. 二.Demo演示 为了说明问题,我使用MVC3项目创建Controller,并且创建如下代码演示: //交通方式枚举 public enum TrafficEnum { Bus = 0, Boat = 1, Bike = 2, } public class Person { pub

如何正确配置hadoop中的namenode

问题描述 如何正确配置hadoop中的namenode 我现在在配置hadoop,可是在格式化hadoop时,提示aborted at /home/user/hadoop/hadoop1.0.2/hdfs/name,不知道什么原因导致了这个问题,请大神们加以指点... 本人初学者,很多还不懂...

CentOS 7.x中正确设置时间与时钟服务器同步

CentOS 7.x中正确设置时间与时钟服务器同步 Chrony是一个开源的自由软件,它能帮助你保持系统时钟与时钟服务器(NTP)同步,因此让你的时间保持精确.它由两个程序组成,分别是chronyd和chronyc.chronyd是一个后台运行的守护进程,用于调整内核中运行的系统时钟和时钟服务器同步.它确定计算机增减时间的比率,并对此进行补偿.chronyc提供了一个用户界面,用于监控性能并进行多样化的配置.它可以在chronyd实例控制的计算机上工作,也可以在一台不同的远程计算机上工作. 在像