1. 程式人生 > >Hibernate級聯操作 註解

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>中

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


相關推薦

Hibernate操作 註解

EJB3 支援的操作型別 /** * Cascade types (can override default EJB3 cascades */ public enum CascadeType { ALL, PERSIST, MERGE, REMOVE, R

Hibernate操作解密(inverse和cascade)

cls any con st2 hset 總結 map 例子 src 總結: Cascade:對級聯操作進行限制,有如下幾個參數:   all : 所有情況下均進行關聯操作。   none:所有情況下均不進行關聯操作。這是默認值。   save-update:在執行sa

Hibernate操作Cascade學之---delete

所在cascade,就是說我在更新一方的時候,可以根據這一方物件之間的關聯關係,去對被關聯方進行持久化,比如說Team和Student之間的1對多關係,使用cascade,可以在team方維護其持有的student集合時,自動對其新增,修改,刪除的student物件進行持久化

Hibernate 操作,對映檔案中的預設的Lazy屬性導致的異常

hibernate中的延遲載入策略一定程度上降低了記憶體開銷,但是有時候使用會出現不想要的異常。 首先,hibernate hbm 中lazy屬性(true|false),在hibernate中預設lazy是true。 Hibernate中允許使用延遲載入的地方主要有以下

hibernate操作詳解

二,屬性的解析 class元素的lazy屬性設定為true,表示延遲載入,如果lazy設為false,則 表示立即載入。以下對這二點進行說明。      立即載入:表示Hibernate在從資料庫中取得資料組裝好一個物件(如學生1)後,             會立即再從資料庫取得資料組裝此物件所關聯的物件(

hibernate的中的查詢與操作

導致 pan 出了 場景 效果 自動保存 情況下 主鍵 只需要 1.Criteria查詢接口適用於組合多個限制條件來搜索一個查詢集。 要使用Criteria,需要遵循以下步驟: *創建查詢接口: Criteria criteria=session.createCrite

hibernate jpa manyToOne操作時,update時報出identifier of an instance of 問題的解決方案及update問題

   最近一直在用Jpa來做專案,jpa的優點這裡我就不多說了,說一下最近使用時解決的一個問題吧。 首先來說,使用jpa進行update操作時,由於呼叫的是jpa封裝好的save方法,所以如果表單頁面中沒有提到的引數,這時儲存的時候,沒有提到的引數就會被置為null,為此我

Hibernate增加一條記錄,操作

在增加一條資訊時,沒有設定級聯操作,於是在資料庫裡每次都會新生成一個model_Id,沒有新增進指定的模組裡。 報錯:object references an unsaved transient instance - save the transient instance

SSH操作報錯:org.hibernate.exception.ConstraintViolationException: Could not execute

SSH整合過程中,刪除具有外來鍵的記錄時報錯: spring4+hibernate4 org.hibernate.exception.ConstraintViolationException: C

hibernate 刪除策略(註解版、資料庫版)

資料庫中的表一般都是相互關聯的,它們通過foreign key產生關係。 定義foreign key約束時可以指定三種引用行為:delete cascade、delete set null、delete no action,預設是delete on action。它們的含義

Hibernate 學習筆記 之 多對多關係 及其 操作

一、多對多配置 User.java /** * Created by Donald on 2016/11/20. */ public class User { priva

hibernate常見操作異常及解決方法

異常1:not-null property references a null or transient value    解決方法:將“一對多”關係中的“一”方,not-null設定為false (參考資料:http://www.thearcmind.com/conflu

Hibernate 學習筆記 之 一對多關係 及其 操作

一、一對多關係 Customer.java /** * Created by Donald on 2016/11/19. */ public class Customer {

Hibernate學習之操作3——一對一關聯關係

前面兩篇博文裡記錄了Hibernate級聯操作的一對多關聯關係和一對多雙向自身關聯關係,這一篇記錄的是一對一關聯關係,例如一個人對應一張身份證,一對一的關係又可以分為共用主鍵的方式和一對多的特殊情況(使用外來鍵關聯)這兩種,下面分別記錄這兩種方式, 一、共用主鍵的一對一關係

Mysql實現操作更新、刪除)

刪除表 null weight .cn eat 失敗 bsp src 成績 一、首先創建兩張表stu,sc create table stu( sid int UNSIGNED primary key auto_increment, name varchar(20) no

jqery對於select操作

ID 網絡 else type lec for bre lse move 問題:今天在做一個需求的時候,有一個級聯操作也就是選中下拉框的一列就顯示對對應的數據 處理:我在做級聯的時候在option的列裏面綁定click的事件發現這個事件行不通;查資料發現select觸發的是

操作

如果 添加 ade 在外 說了 否則 family sof enc 說到級聯刪除不得不先說一下外鍵,外鍵的定義:“如果公共關鍵字在一個關系中是主關鍵字,那麽這個公共關鍵字被稱為另一個關系的外鍵;換而言之,如果關系模式R中的某屬性集不是R的主鍵,而是另一個關系R

hibernate 刪除時候的兩種情況 之(二) 刪除從表,無法刪除關係表

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

MySQL中主表與副表的區別,操作的運用

劃重點: 1 被約束的表稱為副表,約束別人的表稱為主表,外來鍵設定在副表上的。 2 主表被參考的欄位通常都設定為主鍵 3 當有外來鍵約束的時候,新增資料的順序:先加主表,再新增副表的資料 4 當有外來鍵約束的時候,修改資料的順序:先修改副表,再修改主表的資料 5 當有外來鍵約束

mysql004--關聯查詢,外來鍵的操作,常用內建函式

ascii()   --返回字元的sacii碼 char()   --檢視ascii碼對應的字元值 concat(var1,var2,var3)  --字串拼接 length(str)   --返回字元長度 substring(str,start,len) --字串擷取 trim() ltrim()