Hibernate級聯操作 註解


EJB3 支持的操作類型

/**
 * 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
}

級聯更新保存,在Many一端加入如下註解。   如果父類(insert)是自動增長的,請設置 @GeneratedValue

 @JoinColumn(name = "conf_file_id", referencedColumnName = "conf_file_id",insertable = true,updatable = true)
    @Cascade(value = {org.hibernate.annotations.CascadeType.SAVE_UPDATE})

級聯刪除

  @OneToMany(mappedBy = "projectByProPlanId",orphanRemoval=true)
    @Cascade(value = {org.hibernate.annotations.CascadeType.SAVE_UPDATE})

save-update: 級聯保存(load以後如果子對象發生了更新,也會級聯更新). 但它不會級聯刪除
delete: 級聯刪除, 但不具備級聯保存和更新
all-delete-orphan: 在解除父子關係時,自動刪除不屬於父對象的子對象, 也支持級聯刪除和級聯保存更新.
all: 級聯刪除, 級聯更新,但解除父子關係時不會自動刪除子對象. 

delete-orphan:刪除所有和當前對象解除關聯關係的對象 

 

注意:以上設在哪一段就是指對哪一端的操作而言,比如delete,如果設在one的一端的<set>屬性裏,就是當one被刪除的時候,自動刪除所有的子記錄;

如果設在many一端的<many-to-one>標籤裏,就是在刪除many一端的數據時,會試圖刪除one一端的數據,如果仍然有many外鍵引用one,就會報“存在子記錄”的錯誤;如果在one的一端同時也設置了cascade=“delete”屬性,就會發生很危險的情況:刪除many一端的一條記錄,會試圖級聯刪除對應的one端記錄,因爲one也設置了級聯刪除many,所以其他所有與one關聯的many都會被刪掉。

所以,千萬謹慎在many一端設置cascade=“delete”屬性。

故此cascade一般用在<one-to-one>和<one-to-many>中


以下轉載自:http://blog.csdn.net/sinlff/article/details/7342527

很多人對持久層概念搞不清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的放進行級聯刪除無效!


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章