今天定义了一个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.youkuaiyun.com/dengyin2000/archive/2005/06/27/404188.aspx