標籤: all-delete-orphan
當關聯雙方存在父子關係,就可以在 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
如果要把它也刪掉,則設定:
<set name="orders" cascade="all-delete-orphan" inverse="true">
<key column="CUSTOMER_ID" />
<one-to-many class="mypack.Order" />
再運行時就會執行:delete from ORDERS where CUSTOMER_ID=2 and ID=2;
cascade幾種取值:
save-update: 級聯儲存(load以後如果子物件發生了更新,也會串聯更新). 但它不會串聯刪除
delete: 串聯刪除, 但不具備級聯儲存和更新
all-delete-orphan: 在解除父子關係時,自動刪除不屬於父物件的子物件, 也支援串聯刪除和級聯儲存更新.
all: 串聯刪除, 串聯更新,但解除父子關係時不會自動刪除子物件.
delete-orphan:刪除所有和當前對象解除關聯關係的對象
none:...
級聯儲存和串聯更新總是集合在一起的, 所以沒單獨的save 或 updata
我通常會用到none,save-update,all-delete-orphan,而且還是在一對多和多對多的情況
- none就不用說了,在儲存,更新,刪除當前對象時,忽略其關聯的對象
- save-update:在儲存和更新當前對象的時候,級聯儲存,更新關聯對象,在多對多的情況下用的很多,而且一般 不用於一對多,一對多我通常會採用none或者all-delete-orphan
- delete 刪除當前對象,串聯刪除關聯的對象,我從來單獨沒用過
- all 也就是save-update+delete,另外對當前對象執行evict和lock時對關聯對象也執行evict和lock,我從來沒單獨用過
- delete-orphan 刪除所以和當前對象解除關聯的對象,我從來沒單獨用過
- all-delete-orphan 也就是all+delete-orphan,根據需求,我在一對多中經常使用
2009
-
09
-
10如何在JPA 1.0下實現OneToMany的delete-orphan cascade策略
文章分類:Java編程
在JPA 1.0中,cascade的類型包含:MERGE, REFRESH, PERSIST, REMOVE, ALL
用過Hibernate的同學們都知道,以上類型和Hibernate的cascade相比,少了delete-orphan這種類型。而
delete- orphan是很有用的,不知道為什麼JPA 1.0並不支援。聽說JPA 2.0將要加入,呵呵……總之,這再次證明了JPA
1.0的功能只是Hibernate功能的一個不完整的子集。
既然我們的項目選擇了使用JPA 1.0,那麼我們就需要找出在JPA
1.0下實現delete-orphan的方法。好在我們使用JPA的Hibernate實現(相信這也是大部分JPA使用者的使用方式),所以就有了以
下的解決方案,也就是在Entity中加入Hibernate的Annotation:
Java代碼
- import
javax.persistence.CascadeType;
- import
javax.persistence.Entity;
- import
javax.persistence.OneToMany;
- import
javax.persistence.Table;
- import
org.hibernate.annotations.Cascade;
- ...
-
- @Entity
- @Table
(name =
"ORDERS"
)
- public
class
Order
implements
Auditable, Serializable
- {
- ...
-
- @OneToMany
(mappedBy =
"order"
, cascade = CascadeType.ALL)
- @Cascade
(org.hibernate.annotations.CascadeType.DELETE_ORPHAN)
- private
List<OrderItem> orderItems;
-
- ...
- }
import javax.persistence.CascadeType;import javax.persistence.Entity;import javax.persistence.OneToMany;import javax.persistence.Table;import org.hibernate.annotations.Cascade;...@Entity@Table(name = "ORDERS")public class Order implements Auditable, Serializable{ ... @OneToMany(mappedBy = "order", cascade = CascadeType.ALL) @Cascade(org.hibernate.annotations.CascadeType.DELETE_ORPHAN) private List<OrderItem> orderItems; ...}
注意@Cascade(org.hibernate.annotations.CascadeType.DELETE_ORPHAN)這句。經測試
後確認,加入這句後,JPA底層的Hibernate就會完成delete-orphan的動作,沒有這句則不行。Hibernate確實夠強大,發現
JPA 的annotation不管用,如果發現自己的annotation,還是會自己搞定,牛……