Hibernate传播性持久化攻略

开发 后端
Hibernate默认不实现所谓的可到达即Hibernate传播性持久化(persistence by reachability)的策略。每个Hibernate session的基本操作都有对应的级联风格(cascade style)。

本文向大家介绍Hibernate传播性持久化(transitive persistence),可能好多人还不了解Hibernate传播性持久化(transitive persistence),没有关系,看完本文你肯定有不少收获,希望本文能教会你更多东西。

对每一个对象都要执行保存,删除或重关联操作让人感觉有点麻烦,尤其是在处理许多彼此关联的对象的时候。 一个常见的例子是父子关系。考虑下面的例子:

如果一个父子关系中的子对象是值类型(value typed)(例如,地址或字符串的集合)的,他们的生命周期会依赖于父对象,可以享受方便的级联操作(Cascading),不需要额外的动作。

父对象被保存时,这些值类型(value typed)子对象也将被保存;父对象被删除时,子对象也将被删除。 这对将一个子对象从集合中移除是同样有效:Hibernate会检测到,并且因为值类型(value typed)的对象不可能被其他对象引用,所以Hibernate会在数据库中删除这个子对象。

现在考虑同样的场景,不过父子对象都是实体(entities)类型,而非值类型(value typed)(例如,类别与个体,或母猫和小猫)。 实体有自己的生命期,允许共享对其的引用(因此从集合中移除一个实体,不意味着它可以被删除), 并且实体到其他关联实体之间默认没有级联操作的设置。Hibernate默认不实现所谓的可到达即Hibernate传播性持久化(persistence by reachability)的策略。

每个Hibernate session的基本操作 - 包括 persist(), merge(), saveOrUpdate(), delete(), lock(), refresh(), evict(), replicate() - 都有对应的级联风格(cascade style)。 这些级联风格(cascade style)风格分别命名为 create, merge, save-update, delete, lock, refresh, evict, replicate。 如果你希望一个操作被顺着关联关系级联传播,你必须在映射文件中指出这一点。例如:

  1. <one-to-one name="person" cascade="persist"/> 

级联风格(cascade style)是可组合的:

  1. <one-to-one name="person" cascade="persist,delete,lock"/> 

你可以使用cascade="all"来指定全部操作都顺着关联关系级联(cascaded)。 默认值是cascade="none",即任何操作都不会被级联(cascaded)。

注意有一个特殊的级联风格(cascade style) delete-orphan,只应用于one-to-many关联,表明delete()操作 应该被应用于所有从关联中删除的对象。

建议:

通常在关系中应用级联(cascade)没什么意义。 级联(cascade)通常在 关系中比较有用。

如果子对象的寿命限定在父亲对象的寿命之内,可通过指定cascade="all,delete-orphan"将其变为自动生命周期管理的对象(lifecycle object)。

其他情况,你可根本不需要级联(cascade)。但是如果你认为你会经常在某个事务中同时用到父对象与子对象,并且你希望少打点儿字,可以考虑使用cascade="persist,merge,save-update"。

可以使用cascade="all"将一个关联关系(无论是对值对象的关联,或者对一个集合的关联)标记为父/子关系的关联。 这样对父对象进行save/update/delete操作就会导致子对象也进行save/update/delete操作。

此外,一个持久的父对象对子对象的浅引用(mere reference)会导致子对象被同步save/update。 不过,这个隐喻(metaphor)的说法并不完整。除非关联是关联并且被标记为cascade="delete-orphan", 否则父对象失去对某个子对象的引用不会导致该子对象被自动删除。 父子关系的级联(cascading)操作准确语义如下:

如果父对象被persist(),那么所有子对象也会被persist()

如果父对象被merge(),那么所有子对象也会被merge()

如果父对象被save(),update()或 saveOrUpdate(),那么所有子对象则会被saveOrUpdate()

如果某个持久的父对象引用了瞬时(transient)或者脱管(detached)的子对象,那么子对象将会被saveOrUpdate()

如果父对象被删除,那么所有子对象也会被delete()

除非被标记为cascade="delete-orphan"(删除“孤儿”模式,此时不被任何一个父对象引用的子对象会被删除), 否则子对象失掉父对象对其的引用时,什么事也不会发生。 如果有特殊需要,应用程序可通过显式调用delete()删除子对象。

***,注意操作的级联可能是在调用期(call time)或者写入期(flush time)作用到对象图上的。所有的操作,如果允许,都在操作被执行的时候级联到可触及的关联实体上。然而,save-upate和delete-orphan是在Session flush的时候才作用到所有可触及的被关联对象上的。

本文只是大概的说明了Hibernate传播性持久化的应用,可能还有不足的地方,读者可以查更多的书去了解。

【编辑推荐】

  1. Hibernate中Criteria攻略详解
  2. 简述Hibernate三种查询的应用
  3. 谈谈Hibernate为何是Java开源项目
  4. 浅析为何学习Hibernate
  5. 浅析Hibernate VO与PO区别
责任编辑:仲衡 来源: javanb
相关推荐

2009-09-27 09:55:38

Hibernate持久

2009-09-24 15:42:44

Hibernate对象

2009-09-29 16:11:45

Hibernate实现

2009-09-28 15:50:53

Hibernate创建持久化Product

2009-09-29 16:46:01

创建Hibernate

2009-09-25 17:19:28

Hibernate持久

2009-09-25 09:30:33

Hibernate持久

2009-09-23 15:25:08

Hibernate 3

2009-06-17 16:00:03

Hibernate自定

2009-09-23 17:00:07

Hibernate持久

2009-09-21 17:46:34

Hibernate持久

2009-09-29 10:37:29

Hibernate持久

2009-09-29 10:57:25

设置Hibernate

2009-09-24 13:03:38

Hibernate C

2009-09-24 14:12:22

Hibernate数据

2013-07-09 10:18:58

VDI虚拟化

2023-07-07 08:16:53

Redis持久化

2009-06-18 15:24:35

Hibernate二级

2013-09-12 14:56:02

iOS持久化

2021-05-25 10:20:31

Python持久性编程语言
点赞
收藏

51CTO技术栈公众号