Hibernate传播性持久化攻略

*

Hibernate传播性持久化攻略

*http://developer.51cto.com2009-09-2416:39佚名javanb我要评论(1)

Hibernate默认不实现所谓的可到达即Hibernate传播性持久化(persistencebyreachability)的策略。每个Hibernatesession的基本操作都有对应的级联风格(cascadestyle)。

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

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

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

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

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

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

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

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

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

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

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

建议:

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

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

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

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

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

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

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

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

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

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

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

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

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

相关推荐