📄 manipulatingdata.html
字号:
}</pre><p> 如果你是手工管理JDBC事务的,用下面这段: </p><pre class="programlisting">Session sess = factory.openSession();try { // do some work ... sess.flush(); sess.connection().commit();}catch (Exception e) { sess.connection().rollback(); throw e;}finally { sess.close();}</pre><p> 如果你是从JTA中获得数据源的: </p><pre class="programlisting">UserTransaction ut = .... ;Session sess = factory.openSession();try { // do some work ... sess.flush();}catch (Exception e) { ut.setRollbackOnly(); throw e;}finally { sess.close();}</pre></div></div><div class="sect1" lang="zh-cn"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="manipulatingdata-graphs"></a>9.8. 生命周期和对象图(Lifecyles and object graphs)</h2></div></div><div></div></div><p> 要保存或者更新一个对象关联图中所有的所有对象,你必须做到: </p><div class="itemizedlist"><ul type="disc" compact><li><p> 保证每一个对象都执行<tt class="literal">save()</tt>, <tt class="literal">saveOrUpdate()</tt> 或 <tt class="literal">update()</tt>方法,或者, </p></li><li><p> 在定义关联对象的映射时,使用<tt class="literal">cascade="all"</tt>或<tt class="literal">cascade="save-update"</tt>。 </p></li></ul></div><p> 类似的,要删除一个关系图中的所有对象,必须: </p><div class="itemizedlist"><ul type="disc" compact><li><p> 对每一个对象都执行<tt class="literal">delete()</tt>,或者 </p></li><li><p> 在定义关联对象的映射时,使用<tt class="literal">cascade="all"</tt>,<tt class="literal">cascade="all-delete-orphan"</tt>或<tt class="literal">cascade="delete"</tt>。 </p></li></ul></div><p> 建议: </p><div class="itemizedlist"><ul type="disc" compact><li><p> 如果子对象的生命期是绑定到父对象的生命期的,通过指定<tt class="literal">cascade="all"</tt>可以把它变成一个<span class="emphasis"><em>自动管理生命周期的对象(lifecycle object)</em></span>。 </p></li><li><p> 否则,必须在应用程序代码中明确地执行<tt class="literal">save()</tt>和<tt class="literal">delete()</tt>。如果你想少敲一些代码,可以使用<tt class="literal">cascade="sve-update"</tt>,然后只需明确地<tt class="literal">delete()</tt>。 </p></li></ul></div><p> 对一种关联(多对一,或者集合)使用<tt class="literal">cascade="all"</tt>映射,就把这种关联标记为一种<tt class="literal">父/子(parent/child)</tt>风格的关系,对父对象进行保存/更新/删除会导致对(所有)子对象的保存/更新/删除。但是这个比喻并不是特别确切。如果父对象解除了对某个子对象的关联,那这个子对象就<span class="emphasis"><em>不会</em></span>被自动删除了。除非这是一个<tt class="literal">一对多</tt>的关联,并且标明了<tt class="literal">cascade="all-delete-orphan"(所有-删除-孤儿)</tt>。级联操作的精确语义在下面列出: </p><div class="itemizedlist"><ul type="disc" compact><li><p> 如果父对象被保存,所有的子对象会被传递到<tt class="literal">saveOrUpdate()</tt>方法去执行 </p></li><li><p> 如果父对象被传递到<tt class="literal">update()</tt>或者<tt class="literal">saveOrUpdate()</tt>,所有的子对象会被传递到<tt class="literal">saveOrUpdate()</tt>方法去执行 </p></li><li><p> 如果一个临时的子对象被一个持久化的父对象引用了,它会被传递到<tt class="literal">saveOrUpdate()</tt>去执行 </p></li><li><p> 如果父对象被删除了,所有的子对象对被传递到<tt class="literal">delete()</tt>方法执行 </p></li><li><p> 如果临时的子对象不再被持久化的父对象引用,<tt class="literal">什么都不会发生</tt>(必要时,程序应该明确的删除这个子对象),除非声明了<tt class="literal">cascade="all-delete-orphan"</tt>,在这种情况下,成为“孤儿”的子对象会被删除。 </p></li></ul></div><p> Hibernate还没有完全实现“通过可触及性决定持久化”,后者暗示会对垃圾收集进行(效率不高的)持久化。但是,因为很广泛的呼声,Hibernate实现了一种意见,如果一个实体被一个持久化的对象引用,它也会被持久化。注明了<tt class="literal">cascade="save-update"</tt>的关联就是按照这种思路运作的。如果你希望在你的整个程序中都贯彻这个方法,你可以在<tt class="literal"><hibernate-mapping></tt>元素的<tt class="literal">default-cascade</tt>属性中指定这种级联方式。 </p></div><div class="sect1" lang="zh-cn"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="manipulatingdata-interceptors"></a>9.9. 拦截器(Interceptors)</h2></div></div><div></div></div><p> <tt class="literal">Interceptor</tt>接口提供从session到你的应用程序的回调方法,让你的程序可以观察和在持久化对象保存/更改/删除或者装载的时候操作它的属性。一种可能的用途是用来监视统计信息。比如,下面的<tt class="literal">Interceptor</tt>会自动在一个<tt class="literal">Auditable</tt>创建的时候设置其<tt class="literal">createTimestamp</tt>,并且当它被更改的时候,设置其<tt class="literal">lastUpdateTimestamp</tt>属性。 </p><pre class="programlisting">package net.sf.hibernate.test;import java.io.Serializable;import java.util.Date;import java.util.Iterator;import net.sf.hibernate.Interceptor;import net.sf.hibernate.type.Type;public class AuditInterceptor implements Interceptor, Serializable { private int updates; private int creates; public void onDelete(Object entity, Serializable id, Object[] state, String[] propertyNames, Type[] types) { // do nothing } public boolean onFlushDirty(Object entity, Serializable id, Object[] currentState, Object[] previousState, String[] propertyNames, Type[] types) { if ( entity instanceof Auditable ) { updates++; for ( int i=0; i <
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -