`
johnnylzb
  • 浏览: 12794 次
  • 性别: Icon_minigender_1
  • 来自: 广州
文章分类
社区版块
存档分类

关于关联对象的级联删除的问题。(应用于“充血模型”)

阅读更多
用例是这样的:

现在有A、B两个对象,彼此关系是 A 1 : n B

换言之,A之中就有一个集合引用了B,现在我想通过调用 A.removeB(B b)方法,Hibernate就能透明的把B从数据库中删除掉,这样做的好处主要在于在“充血模型”中,领域对象有聚合根,所有对领域对象的操作必须由聚合根发起,上面的例子中,A是B的聚合根,因此需要删除B,则必须通过A发起。应用层的代码如下:


 
public class SomeService {
    public removeBFromA(Long bId,Long aId) {
        B b = bDao.get(bId);
        A a = aDao.get(aId);
        a.removeB(b);
    } 


我通过Hibernate设置了A、B的一对多关系,通过“mappedby”设置了B为主动方(主要是考虑插入数据的时候,不需要对B的外键调用多一次Update语句),casdaceType是ALL,但我发现,当删除A的时候,确实可以级联删除B,但当调用A.remove(B)的时候,只能把B的外键清空,并没有把B删除掉,而如果我尝试把B的外键的nullable设置为false,在调用b.setA(null)的时候,还会出现数据完整性异常,所以,根本无法通过A来发起对B的删除操作。(除非把B的DAO放置到A中,由A.removeB()方法显式调用DAO的方法删除B,但这就把持久化逻辑加入到领域对象中了,而持久化逻辑应该完全由应用层Servcie完成)。

于是,最终不得不把上面的代码改为:


 
public class SomeService {
    public removeBFromA(Long bId,Long aId) {
        B b = bDao.get(bId);
        A a = aDao.get(aId);
        a.removeB(b);
        bDao.remove(b); // 领域层的客户代码必须显式的删除B
    } 


上面的代码表面上没问题,但事实上,应用层必须显式的去删除B,这样做就不太优雅了,因为领域层把A管理B生命周期的细节泄漏到应用层了。

不知大家有没有什么好的办法解决这个问题。
分享到:
评论
6 楼 ice123456 2008-10-29  
Quake Wang 写道
cascade 设置 all-delete-orphan
A的remove方法里面,将B从集合移除,同时将其parent设null
这样在session生命周期结束的时候,将会自动进行级联删除,你不需要调用dao的任何方法。

貌似用级联删除的时候,hibernate是一条条的删除,这点感觉不爽
5 楼 johnnylzb 2008-10-29  
可以了,谢谢
4 楼 QuakeWang 2008-10-29  
delete-orphan是Hibernate对JPA的扩展,你可以直接使用
http://www.hibernate.org/hib_docs/annotations/api/org/hibernate/annotations/CascadeType.html
3 楼 johnnylzb 2008-10-29  
Quake Wang 写道
cascade 设置 all-delete-orphan
A的remove方法里面,将B从集合移除,同时将其parent设null
这样在session生命周期结束的时候,将会自动进行级联删除,你不需要调用dao的任何方法。


请问orphan是什么意思呢?我使用的是J2EE的Persistent API,CascadeType并没有ORPHAN
2 楼 QuakeWang 2008-10-29  
cascade 设置 all-delete-orphan
A的remove方法里面,将B从集合移除,同时将其parent设null
这样在session生命周期结束的时候,将会自动进行级联删除,你不需要调用dao的任何方法。
1 楼 johnnylzb 2008-10-29  
补充一下,以下是 A.removeB()的实现逻辑

    public void removeB(B b) {
        getChildren().remove(b); // 在A属性的保存B的列表中把B清掉
         b.setParent(null); // 由于B是主动控制方,需要在这里显示把B中的A引用设置为null
    }


以下是在B当中的Hibernate设置

@ManyToOne(fetch = FetchType.EAGER)
	@JoinColumn(name = "A_FK" ,nullable=true)
	public A getParent() {
		return parent;
	}


以下是A当中的Hibernate设置:

	@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
	public List<B> getChildren() {
		return children;
	}

相关推荐

    hibernate基础 二 关联映射 级联操作

    ### Hibernate基础之关联映射与级联操作 ...以上是关于Hibernate中关联映射和级联操作的基础知识概述,掌握了这些内容后,开发者能够在实际项目中更加灵活高效地使用Hibernate进行数据持久化操作。

    mybatis关联/级联以及动态sql

    MyBatis是一个优秀的持久层框架...总之,MyBatis的关联和级联特性使得对象关系映射更加自然,动态SQL则让数据库操作变得更加灵活和高效。理解并熟练运用这些功能,将极大地提升你在处理数据库交互时的效率和代码质量。

    JPA中的一对多双向关联与级联操作

    在Java Persistence API (JPA) 中,一对...总的来说,JPA的一对多双向关联及级联操作为开发者提供了便利,但也需要注意合理配置以避免潜在的问题。在实际开发中,我们需要根据业务需求和性能考虑来选择合适的关联策略。

    MSserver自关联表的级联删除

    然而,自关联表的级联删除并不像简单的外键级联删除那样直接,因为它涉及到了递归关系。 在上述标题和描述中提到的MS Server自关联表的级联删除,主要通过触发器来实现。触发器是一种特殊的存储过程,它会在特定的...

    python-opencv Haar LBP级联分类器下载,训练模型

    这些模型可以直接应用于OpenCV的`cv2.CascadeClassifier()`函数,进行物体检测,如人脸识别、行人检测或其他自定义的目标检测任务。 使用这些模型的基本步骤如下: 1. 解压文件,获取`.xml`模型文件。 2. 在Python...

    10_JPA详解_JPA中的一对多双向关联与级联操作.zip

    本资料包"10_JPA详解_JPA中的一对多双向关联与级联操作.zip"聚焦于JPA中的一个重要概念——一对多双向关联及其级联操作。以下是对这一主题的详细阐述。 **一对多关联** 在关系数据库设计中,一对多关联是最常见的...

    10_传智播客JPA详解_JPA中的一对多双向关联与级联操作

    在实际应用中,需要注意的是,虽然双向关联和级联操作带来了很多便利,但也可能导致性能问题,因为它们会增加数据库查询的复杂性和数据的冗余。因此,在设计数据模型时,应权衡易用性和效率,合理使用这些特性。 本...

    关于Hibernate级联删除的问题.doc

    级联删除(Cascade Delete)就是其中之一,当删除一个对象时,会根据配置自动删除与之相关联的对象。在文档中提到的场景下,我们来详细探讨Hibernate级联删除的原理和配置方法。 首先,我们要理解关系映射中的几个...

    74HC595 级联-时钟偏移问题.pdf

    通过研究发现,时钟偏移问题是 SN74HC595 级联应用中的一个关键问题。时钟偏移会导致 SN74HC595 的输出出错,影响系统的稳定性和可靠性。 在了解 SN74HC595 的基本知识后,我们可以更好地理解时钟偏移问题的产生...

    qt实现sqlite3级联删除demo

    在数据库管理中,级联删除是一种常见的功能,它允许在删除一个表中的记录时,自动删除与之相关联的其他表中的记录。在Qt环境下,结合SQLite3数据库,我们可以实现这一功能。Qt是一个跨平台的C++库,提供了丰富的GUI...

    hibernate many-to-many级联保存,级联更新,级联删除

    当调用`session.delete(student)`或`session.delete(course)`时,如果配置了级联删除,Hibernate会检查关联表,找出所有与被删除实体关联的记录,并一并删除。请注意,级联删除可能引起数据丢失,因此在使用时需谨慎...

    MySQL中利用外键实现级联删除、更新

    "MySQL 中利用外键实现级联删除、更新" 在 MySQL 中,外键是指在一个表中的一列或多列,引用另一个表中的主键或唯一索引。外键可以强制实施数据的一致性和完整性,使得数据更加可靠。外键在 MySQL 中的实现主要是...

    mysql级联更新和级联删除

    ### MySQL级联更新与级联删除详解 在数据库设计中,外键约束是维护数据完整性和一致性的重要手段之一。MySQL的InnoDB存储引擎支持多种不同的处理外键的方式,包括级联更新(Cascade Update)和级联删除(Cascade ...

    级联菜单 动态级联菜单

    级联菜单广泛应用于各种Web应用程序中,例如电商平台、在线教育平台、政府网站等等。动态级联菜单可以根据实际情况动态生成选项,提高用户体验和工作效率。 结论 级联菜单是一种常见的Web应用程序用户界面元素,...

    级联删除笔记【自用0分】

    级联删除和级联更新是数据库管理中非常重要的概念,特别是在多表关联的情况下,能够确保数据的一致性和完整性。本文将详细介绍如何在SQL Server中实现级联更新和级联删除,包括通过触发器的方式和使用外键约束的方式...

    无标度网络级联失效(基于载荷容量模型).zip_复杂网络 matlab_无标度网络 matlab_级联失效 matlab_鲁棒性

    无标度网络级联失效是复杂网络研究中的一个重要主题,主要关注网络在遭受局部失效后如何影响整体系统稳定性的问题。这个MATLAB代码实现了一个基于载荷容量模型的级联失效模拟,以分析网络的鲁棒性。下面我们将深入...

    SQL server创建触发器实现级联删除

    ### SQL Server 创建触发器实现级联删除 在数据库管理中,触发器是一种特殊类型的存储过程,它被设计为响应特定的事件(如插入、更新或删除数据)而自动执行。本文将详细介绍如何在 SQL Server 中创建一个触发器来...

    SSH+级联菜单应用案例

    在级联菜单应用中,它用于将菜单数据模型与数据库表进行映射,提供CRUD(创建、读取、更新、删除)操作。级联菜单的数据通常存储在多层关联的表结构中,Hibernate可以通过HQL(Hibernate Query Language)或 ...

    用JDBC实现数据库的级联删除与更新

    根据给定文件的信息,本文将围绕“用JDBC实现数据库的级联删除与更新”这一主题进行深入探讨,包括理解需求、设计思路、具体实现步骤以及相关代码示例。 ### 1. 需求理解 #### 1.1 业务场景 在本案例中,存在两个...

Global site tag (gtag.js) - Google Analytics