hibernate中cascade的理解。

    技术2022-05-11  87

    今天定义了一个one to many 的关联对象。

    <?xml version="1.0"?><!DOCTYPE hibernate-mapping PUBLIC    "-//Hibernate/Hibernate Mapping DTD 2.0//EN"    "http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd" >

    <hibernate-mapping>  <class name="fsi.hibernate.beans.FSISynthetic" table="FSISYNTHETIC">   <id name="objectId" type="java.lang.Integer" column="OBJECTID">   <generator class="fsi.hibernate.custom.idgen.FSIIdGenerator">    <param name="table_name">FSISYNTHETIC</param>   </generator>  </id>    <property name="cusip" column="CUSIP" type="java.lang.String" />    <property name="underlyingSecurityID" column="UNDERLYINGSECURITYID" type="java.lang.String" length="255" />    <property name="initialCoupon" column="INITIALCOUPON" type="double" />    <property name="initialResetPeriod" column="INITIALRESETPERIOD" type="double" />    <property name="resetPeriodicity" column="RESETPERIODICITY" type="double" />    <property name="indexType" column="INDEXTYPE" type="int" />    <property name="securityLoadOrderName" column="SECURITYLOADORDERNAME" type="string" length="255" />    <property name="multiplier" column="MULTIPLIER" type="double" />    <property name="spread" column="SPREAD" type="double" />

      <property name="cap" column="CAP" type="double" />      <property name="floor" column="FLOOR" type="double" />     <property name="contributingFractionOfUnderlyingInterest" column="CONTRIBUTINGFRACTIONOFUI" type="double" />       <property name="fractionOfUnderlyingPrincipal" column="FRACTIONOFUP" type="double" />     <property name="weighting" column="WEIGHTING" type="double" />      <property name="price" column="PRICE" type="double" />    <set name="children" lazy="true" inverse="true" cascade="all">   <key column="PARENTID"/>    <one-to-many class="fsi.hibernate.beans.FSISyntheticItem"/>    </set>   </class> 

    </hibernate-mapping>

    <?xml version="1.0"?><!DOCTYPE hibernate-mapping PUBLIC    "-//Hibernate/Hibernate Mapping DTD 2.0//EN"    "http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd" >

    <hibernate-mapping>  <class name="fsi.hibernate.beans.FSISyntheticItem" table="FSISYNTHETICITEM">   <id name="objectId" type="java.lang.Integer" column="OBJECTID">   <generator class="fsi.hibernate.custom.idgen.FSIIdGenerator">    <param name="table_name">FSISYNTHETICITEM</param>   </generator>  </id>    <property name="childName" column="ITEMNAME" type="string" length="12" not-null="true" />    <many-to-one name="parent" column="PARENTID" class="fsi.hibernate.beans.FSISynthetic" not-null="true" />   </class> 

    </hibernate-mapping>

     

    开始我定义cascade为 all,在parent方插入一个父亲,然后分别插入几个child。

    /* * Created on 2005-6-24 */package test;

    import net.sf.hibernate.HibernateException;import net.sf.hibernate.Session;import fsi.hibernate.beans.FSISynthetic;import fsi.hibernate.beans.FSISyntheticItem;import fsi.hibernate.session.utils.HibernateUtil;

    /** *   @author deng.yin(邓胤) */public class Test {    public static void main(String[] args) throws HibernateException{        Session session = HibernateUtil.getSession();        HibernateUtil.beginTransaction();        FSISynthetic syn = (FSISynthetic) session.load(FSISynthetic.class,new Integer(256));        FSISyntheticItem child = (FSISyntheticItem) session.load(FSISyntheticItem.class,new Integer(1));        syn.getChildren().remove(child);        session.saveOrUpdate(syn);        HibernateUtil.commitTransaction();        HibernateUtil.closeSession();    }}

    用这段代码测试后发现指定的这个child

    FSISyntheticItem child = (FSISyntheticItem) session.load(FSISyntheticItem.class,new Integer(1));并没有删掉。

    我感到奇怪。于是打开hibernate文档。

    还是看的不够认真。

     

    要保存或者更新一个对象关联图中所有的所有对象,你必须做到:

    保证每一个对象都执行save(), saveOrUpdate() 或 update()方法,或者,

    在定义关联对象的映射时,使用cascade="all"或cascade="save-update"。

    类似的,要删除一个关系图中的所有对象,必须:

    对每一个对象都执行delete(),或者

    在定义关联对象的映射时,使用cascade="all",cascade="all-delete-orphan"或cascade="delete"。

    建议:

    如果子对象的生命期是绑定到父对象的生命期的,通过指定cascade="all"可以把它变成一个自动管理生命周期的对象(lifecycle object)

    否则,必须在应用程序代码中明确地执行save()和delete()。如果你想少敲一些代码,可以使用cascade="sve-update",然后只需明确地delete()。

    对一种关联(多对一,或者集合)使用cascade="all"映射,就把这种关联标记为一种父/子(parent/child)风格的关系,对父对象进行保存/更新/删除会导致对(所有)子对象的保存/更新/删除。但是这个比喻并不是特别确切。如果父对象解除了对某个子对象的关联,那这个子对象就不会被自动删除了。除非这是一个一对多的关联,并且标明了cascade="all-delete-orphan"(所有-删除-孤儿)。级联操作的精确语义在下面列出:

    如果父对象被保存,所有的子对象会被传递到saveOrUpdate()方法去执行

    如果父对象被传递到update()或者saveOrUpdate(),所有的子对象会被传递到saveOrUpdate()方法去执行

    如果一个临时的子对象被一个持久化的父对象引用了,它会被传递到saveOrUpdate()去执行

    如果父对象被删除了,所有的子对象对被传递到delete()方法执行

    如果临时的子对象不再被持久化的父对象引用,什么都不会发生(必要时,程序应该明确的删除这个子对象),除非声明了cascade="all-delete-orphan",在这种情况下,成为“孤儿”的子对象会被删除。

    Hibernate还没有完全实现“通过可触及性决定持久化”,后者暗示会对垃圾收集进行(效率不高的)持久化。但是,因为很广泛的呼声,Hibernate实现了一种意见,如果一个实体被一个持久化的对象引用,它也会被持久化。注明了cascade="save-update"的关联就是按照这种思路运作的。如果你希望在你的整个程序中都贯彻这个方法,你可以在<hibernate-mapping>元素的default-cascade属性中指定这种级联方式。

    我把cascade="all" 改成cascade="all-delete-orphan"后,就ok了

     -----引自 http://blog.csdn.net/dengyin2000/archive/2005/06/27/404188.aspx

    最新回复(0)