hibernate cascade 备忘

摘自 孙卫琴 精通Hibernate P159

当关联双方存在父子关系,就可以在 set 处设定 cascade 为 all-delete-orphan

所谓父子关系,即指由父方控制子方的持久化圣明周期,子方对象必须和一个父方对象关联。如果删除父方对象,应该级联删除所有关联的子方对象;如果一个子方对象不再和一个父方对象关联,应该把这个子方对象删除。

all-deleteorphan 的能力:

1. 当保存或更新父方对象时,级联保存或更新所有关联的子方对象,相当于 cascade 为 save-update

2. 当删除父方对象时,级联删除所有关联的子方对象,相当于 cascade 为 delete

3. 删除不再和父方对象关联的所有子方对象

解除父子关系的 java 语句例如:

customer.getOrders().remove(order);
order.setCustomer(null);

tx.commit();

如果 cascade 属性取默认值 null,当解除父子关系时,会执行如下 sql:

update ORDER set CUSTOMER_ID=null where ID=2

inverse 设定的原则:

1. 在映射一对多双向关联关系时,应该设定 many 方的 inverse 为 true,以提高性能

2. 在建立两个对象的双向关联时,应同时修改关联两端的对象的相应属性:

1)customer.getOrders().add(order);
2)order.setCustomer(customer);

如果不执行 1)而仅执行 2),由于 set 元素的 inverse 为 true,因此 hibernate 不会按照 CUSTOMER 对象的状态变化来同步数据库。

inverse 解决性能问题的例子:

1. 建立 Order 到 Customer 的多对一关联关系

order.setCustomer(customer);

相应执行的 SQL 为:

update ORDERS set ORDER_NUMBER='Jack_Order001', CUSTOMER_ID=2 where ID=2;

2. 建立 Customer 到 Order 的一对多关系

customer ORDERS set CUSTOMER_ID=2 where ID=2;

相应 SQL 为:

update ORDERS set CUSTOMER_ID=2 where ID=2;

显然 1 和 2 的 SQL 功能重复了,反复执行这样的 SQL 语句会引起性能下降,因此:

inverse 设定为 true 时,声明 Customer 端的关联只是 Order 端关联的镜像。当两者状态发生变化时,Hibernate 仅按照 Order 对象状态变化来同步数据库。即仅会执行以下 SQL:

update ORDERS set ORDER_NUMBER='Jack_Order001', CUSTOME_ID=2 where ID=2;

Customer.hbm.xml 片段如下:

<set
name="orders"
cascade="all-delete-orphan"
inverse="true"
>
<key column="CUSTOMER_ID" />
<one-to-many class="mypack.Order" />
</set>

你可能感兴趣的:(Hibernate)