hibernate的級聯操作

來源:互聯網
上載者:User

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

 

 

one-to-many中設定串聯刪除,比如:

<set<br /> name="entryvalues"<br /> lazy="false"<br /> inverse="true"<br /> order-by="VALUEID"<br /> cascade="all-delete-orphan"<br /> ><br /> <key><br /> <column name="CONTEXTENTRYID" /><br /> </key><br /> <one-to-many<br /> class="Entryvalue"<br /> /><br /> </set><br />

如果用Hiberante的SchemaExport匯出表到資料庫,是不會在資料庫中設定外鍵的cascade屬性的,查看ENTRYVALUE表,其中的外鍵CONTEXTENTRYID的on delete屬性是no action

但是使用Hiberante管理事務,它是會維護這種級聯關係的,比如這樣操作:

public void testCascadeDelete() {<br />Session s = HibernateUtil.getSession();<br />Transaction tx;<br />try {<br />tx = s.beginTransaction();<br />Contextentry ce = (Contextentry)s.load(Contextentry.class, new Long(1));</p><p>s.delete(ce);<br />tx.commit();</p><p>} catch (HibernateException e) {<br />// TODO Auto-generated catch block<br />e.printStackTrace();<br />}<br />}

則引用此Contextentry的Entryvalue是會被正確串聯刪除的.

 

如果使用普通JDBC操作,比如:

public void testCascadeDeleteSQL() {<br />Session s = HibernateUtil.getSession();<br />Transaction tx;<br />String sql = "delete contextentry where id=4";<br />try {<br />tx = s.beginTransaction();<br />Connection con = s.connection();<br />Statement st = con.createStatement();<br />st.execute(sql);<br />tx.commit();<br />} catch (HibernateException e) {<br />// TODO Auto-generated catch block<br />e.printStackTrace();<br />} catch (SQLException e) {<br />// TODO Auto-generated catch block<br />e.printStackTrace();<br />}<br />}

則會報"存在子記錄"的錯誤,這裡的Transaction實際上是無效的,因為用的是JDBC的Connection和Statement,已經脫離了Hibernate的管理.如果手動將ENTRYVALUE表的相關外鍵ON DELETE屬性設為CASCADE,則上面的操作當然正確執行——串聯刪除子記錄

 

 

all-delete-orphan 的能力:
1. 當儲存或更新父方對象時,級聯儲存或更新所有關聯的子方對象,相當於 cascade 為 save-update
2. 當刪除父方對象時,串聯刪除所有關聯的子方對象,相當於 cascade 為 delete
3. 刪除不再和父方對象關聯的所有子方對象,當然,“不再和父方對象關聯的所有子方對象”必須是在本次事務中發生的。

 解除父子關係的 java 語句例如:
public void testCascadeDelete() {<br />Session s = HibernateUtil.getSession();<br />Transaction tx;<br />try {<br />tx = s.beginTransaction();<br />Contextentry ce = (Contextentry)s.load(Contextentry.class, new Long(5));</p><p>Entryvalue ev = (Entryvalue)s.load(Entryvalue.class, new Long(10));<br />ev.setContextentry(null);</p><p>s.delete(ce);<br />tx.commit();</p><p>} catch (HibernateException e) {<br />// TODO Auto-generated catch block<br />e.printStackTrace();<br />}<br />}
如果 cascade 屬性取預設值 null,當解除父子關係時,會執行如下 sql:
update ENTRYVALUE set CONTEXTENTRYID=null where ID=10
即將對應外鍵置為null,而使用all-delete-orphan,則會在相關事務執行的時候,將孤兒子記錄刪除

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.