EJB3 支持的操做類型java
/** * Cascade types (can override default EJB3 cascades */ public enum CascadeType { ALL, PERSIST, MERGE, REMOVE, REFRESH, DELETE, SAVE_UPDATE, REPLICATE, /** @deprecated use @OneToOne(orphanRemoval=true) or @OneToMany(orphanRemoval=true) */ @Deprecated DELETE_ORPHAN, LOCK, /** @deprecated use javax.persistence.CascadeType.DETACH */ @Deprecated EVICT, DETACH }
級聯更新保存session
@JoinColumn(name = "conf_file_id", referencedColumnName = "conf_file_id",insertable = true,updatable = true) @Cascade(value = {org.hibernate.annotations.CascadeType.SAVE_UPDATE})
級聯刪除app
@OneToMany(mappedBy = "projectByProPlanId",orphanRemoval=true) @Cascade(value = {org.hibernate.annotations.CascadeType.SAVE_UPDATE})
save-update: 級聯保存(load之後若是子對象發生了更新,也會級聯更新). 但它不會級聯刪除
delete: 級聯刪除, 但不具有級聯保存和更新
all-delete-orphan: 在解除父子關係時,自動刪除不屬於父對象的子對象, 也支持級聯刪除和級聯保存更新.
all: 級聯刪除, 級聯更新,但解除父子關係時不會自動刪除子對象. ide
delete-orphan:刪除全部和當前對象解除關聯關係的對象 性能
注意:以上設在哪一段就是指對哪一端的操做而言,好比delete,若是設在one的一端的<set>屬性裏,就是當one被刪除的時候,自動刪除全部的子記錄;this
若是設在many一端的<many-to-one>標籤裏,就是在刪除many一端的數據時,會試圖刪除one一端的數據,若是仍然有many外鍵引用one,就會報「存在子記錄」的錯誤;若是在one的一端同時也設置了cascade=「delete」屬性,就會發生很危險的狀況:刪除many一端的一條記錄,會試圖級聯刪除對應的one端記錄,由於one也設置了級聯刪除many,因此其餘全部與one關聯的many都會被刪掉。編碼
因此,千萬謹慎在many一端設置cascade=「delete」屬性。spa
故此cascade通常用在<one-to-one>和<one-to-many>中.net
如下轉載自:http://blog.csdn.net/sinlff/article/details/7342527hibernate
不少人對持久層概念搞不清JPA、Hibernate、EJB3.0的關係,這裏作一下簡單的說明:JPA是一個持久層設計接口,EJB3.0和Hibernate是具體的實現類,EJB3.0和Hibernate的功能近似相等的(Hibernate沒有Session Bean,Spring MVC3的SessionAttribute跟Session Bean近似)。
理論是使用JPA接口能夠無縫切換持久層實現,可是僅僅是理論上!!!
JPA是在Hibernate成熟並大行其道的時候才推出的,基本上是借鑑Hibernate的優勢,作了一個統一的標準而已,JPA1.0沒有一對多的級聯刪除配置,也許JPA2.0裏纔有吧(這裏沒作過調研)
@OneToMany(mappedBy = "commentTeam")
@Cascade({org.hibernate.annotations.CascadeType.SAVE_UPDATE,org.hibernate.annotations.CascadeType.DELETE_ORPHAN})
private Set<CommentTeamMember> commentTeamMembers;
這裏爲了說明,只貼出一對多的關鍵代碼,其它無關的註解已忽略掉,以避免形成干擾。
這裏重點說明一下四個經常使用的註解配置的區別:
CascadeType.SAVE_UPDATE
CascadeType.ALL
CascadeType.DELETE
CascadeType.DELETE_ORPHAN
之全部之列出這四個,是由於我不想跟書本上把全部的概念都羅列出來。基本上開發時其中的3個都以及足夠用了,下面我結合代碼演示一下他們之間的區別,以及使用的時候注意的地方。
CascadeType.SAVE_UPDATE:Hibernate專有的,JPA並不支持,做用是級聯保存、級聯更新(注:JPA很噁心,要麼你配置
CascadeType.ALL,要麼你配CascadeType.SAVE+CasadeType.Merge。八卦一句:專家雖牛,多年不寫代碼,定的標準讓編碼麻煩呀!)
CascadeType.ALL:級聯保存、修改、刪除、同步,通常不多用,看看控制檯的一長串SQL就知道性能低下,你沒改的關聯表也給你發update語句,我歷來沒用過這個屬性。
CascadeType.DELETE:當調用session.delete(A)的時候,級聯刪除關聯的對象。(注:先調用A.setB(null),再調用session.delete(A),這樣是級聯刪不掉B的。
CascadeType.DELETE_ORPHAN:一對多級聯刪除。
下面重點來講說這個CascadeType.DELETE_ORPHAN:
看過API、開發指南,級聯刪除就一個經典的
@OneToMany(mappedBy = "commentTeam")
@Cascade({CascadeType.SAVE_UPDATE,CascadeType.DELETE_ORPHAN})
private Set<CommentTeamMember> commentTeamMembers;
mappedBy不可少,映射A->B一對多的另外一邊控制反轉(誰控誰的問題),新版的Hibernate3.4中配置更簡單,變一句了,更簡潔吧?
@OneToMany(mappedBy = "commentTeam",orphanRemoval=true)
private Set<CommentTeamMember> commentTeamMembers;
CommentTeam commentTeam=this.getHibernateTemplate.get(CommentTeam.class,id);
commentTeam.setCommentTeamMember(null);//想級聯刪除子表數據
this.getHibernateTemplate.saveOrUpdate(commentTeam);
這樣級聯刪除卻沒有發生,爲何呢?
再來一個例子
CommentTeam commentTeam=this.getHibernateTemplate.get(CommentTeam.class,id);
Set<CommentTeamMember> commentTeamMembers=new HashSet<CommentTeamMember>();
commentTeam.setCommentTeamMember(commentTeamMembers);//想級聯刪除子表數據或增減替換對象
this.getHibernateTemplate.saveOrUpdate(commentTeam);
這個例子級聯刪除的效果也沒發生!即便commentTeamMembers裏有若干個對象。
成功執行級聯刪除的語法:
CommentTeam commentTeam=this.getHibernateTemplate.get(CommentTeam.class,id);
commentTeam.getCommentTeamMember().clear();//注意這裏引用的集合仍是原來的集合,這裏沒有從新new過
commentTeam.getCommentTeamMember().add(new CommentTeamMember());//若是想替換爲新的集合能夠用addAll方法
this.getHibernateTemplate.saveOrUpdate(commentTeam);
分析一下緣由:級聯刪除起做用的前提是關聯的集合對象不能從新指向新的引用,必須在原有的集合裏操做新增、刪除、清空元素,像上面的setXXX(null)的方法等是起不到級聯刪除做用的,大概是Hibernate自認本身原生的集合對象吧,本身New的放進行級聯刪除無效!