📄 persistent-classes.html
字号:
}</pre><p> 记住我们的候选关键字(这个例子中是名字和生日的组合)只在特定的比较操作中有效(可能只在一个用例中)。我们不需要我们通常用于正式主键那么严格稳定的条件。 </p></div><div class="sect1" lang="zh-cn"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="persistent-classes-lifecycle"></a>4.4. 持久化生命周期(Lifecycle)中的回调(Callbacks)</h2></div></div><div></div></div><p> 作为一个可选的步骤,可持久化类可以实现<tt class="literal">Lifecycle</tt>接口,它可以提供一些用于回调的方法,可以让持久化对象在save或load之后,或者在delete或update之前进行必要的初始化与清除步骤。 </p><p> Hibernate <tt class="literal">Interceptor</tt>(拦截器)还提供了一种较少干扰的替代方法。 </p><div class="programlistingco"><pre class="programlisting">public interface Lifecycle { public boolean onSave(Session s) throws CallbackException; <span class="co">(1)</span> public boolean onUpdate(Session s) throws CallbackException; <span class="co">(2)</span> public boolean onDelete(Session s) throws CallbackException; <span class="co">(3)</span> public void onLoad(Session s, Serializable id); <span class="co">(4)</span>}</pre><div class="calloutlist"><table border="0" summary="Callout list"><tr><td width="5%" valign="top" align="left">(1)</td><td valign="top" align="left"><p> <tt class="literal">onSave</tt> - 在对象即将被save或者insert的时候回调 </p></td></tr><tr><td width="5%" valign="top" align="left">(2)</td><td valign="top" align="left"><p> <tt class="literal">onUpdate</tt> - 在对象即将被update的时候回调(也就是对象被传递给<tt class="literal">Session.update()</tt>的时候) </p></td></tr><tr><td width="5%" valign="top" align="left">(3)</td><td valign="top" align="left"><p> <tt class="literal">onDelete</tt> - 在对象即将被delete(删除)的时候回调 </p></td></tr><tr><td width="5%" valign="top" align="left">(4)</td><td valign="top" align="left"><p> <tt class="literal">onLoad</tt> - 在对象刚刚被load(装载)后的时候回调 </p></td></tr></table></div></div><p> <tt class="literal">onSave()</tt>, <tt class="literal">onDelete()</tt> 和 <tt class="literal">onUpdate()</tt> 可以被用来级联保存或者删除依赖的对象。这种做法是在映射文件中声明级联操作外的另外一种选择。<tt class="literal">onLoad()</tt>可以用来让对象从其持久化(当前)状态中初始化某些暂时的属性。不能用这种方式来装载依赖的对象,因为可能无法在此方法内部调用<tt class="literal">Session</tt>接口。 <tt class="literal">onLoad()</tt>, <tt class="literal">onSave()</tt>和 <tt class="literal">onUpdate()</tt>另一种用法是用来在当前<tt class="literal">Session</tt>中保存一个引用,已备后用。 </p><p> 请注意<tt class="literal">onUpdate()</tt>并不是在每次对象的持久化状态被更新的时候就被调用的。它只在处于尚未被持久化的对象被传递给<tt class="literal">Session.update()</tt>的时候才会被调用。 </p><p> 如果<tt class="literal">onSave()</tt>, <tt class="literal">onUpdate()</tt> 或者 <tt class="literal">onDelete()</tt>返回<tt class="literal">true</tt>,那么操作就被悄悄地取消了。如果其中抛出了<tt class="literal">CallbackException</tt>异常,操作被取消,这个异常会被继续传递给应用程序。 </p><p> 请注意<tt class="literal">onSave()</tt>是在标识符已经被赋予对象后调用的,除非是使用本地(native)方式生成关键字的。 </p></div><div class="sect1" lang="zh-cn"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="persistent-classes-validatable"></a>4.5. 合法性检查(Validatable)回调</h2></div></div><div></div></div><p> 如果持久化类需要在保存其持久化状态前进行合法性检查,它可以实现下面的接口: </p><pre class="programlisting">public interface Validatable { public void validate() throws ValidationFailure;}</pre><p> 如果发现对象违反了某条规则,应该抛出一个<tt class="literal">ValidationFailure</tt>异常。在<tt class="literal">Validatable</tt>实例的<tt class="literal">validate()</tt>方法内部不应该改变它的状态。 </p><p> 和<tt class="literal">Lifecycle</tt>接口的回调方法不同,<tt class="literal">validate()</tt>可能在任何时间被调用。应用程序不应该把<tt class="literal">validate()</tt>调用和商业功能联系起来。 </p></div><div class="sect1" lang="zh-cn"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="persistent-classes-xdoclet"></a>4.6. XDoclet标记示例</h2></div></div><div></div></div><p> 下一章中我们将会展示Hibernate映射是如何用简单的,可阅读的XML格式表达的。很多Hibernate用户喜欢使用XDoclet的<tt class="literal">@hibernate.tags</tt>标签直接在源代码中嵌入映射信息。我们不会在这份文档中讨论这个话题,因为严格的来说这属于XDoclet的一部分。但我们仍然在这里给出一份带有XDoclet映射的<tt class="literal">Cat</tt>类的示例。 </p><pre class="programlisting">package eg;import java.util.Set;import java.util.Date;/** * @hibernate.class * table="CATS" */public class Cat { private Long id; // identifier private Date birthdate; private Cat mate; private Set kittens private Color color; private char sex; private float weight; /** * @hibernate.id * generator-class="native" * column="CAT_ID" */ public Long getId() { return id; } private void setId(Long id) { this.id=id; } /** * @hibernate.many-to-one * column="MATE_ID" */ public Cat getMate() { return mate; } void setMate(Cat mate) { this.mate = mate; } /** * @hibernate.property * column="BIRTH_DATE" */ public Date getBirthdate() { return birthdate; } void setBirthdate(Date date) { birthdate = date; } /** * @hibernate.property * column="WEIGHT" */ public float getWeight() { return weight; } void setWeight(float weight) { this.weight = weight; } /** * @hibernate.property * column="COLOR" * not-null="true" */ public Color getColor() { return color; } void setColor(Color color) { this.color = color; } /** * @hibernate.set * lazy="true" * order-by="BIRTH_DATE" * @hibernate.collection-key * column="PARENT_ID" * @hibernate.collection-one-to-many */ public Set getKittens() { return kittens; } void setKittens(Set kittens) { this.kittens = kittens; } // addKitten not needed by Hibernate public void addKitten(Cat kitten) { kittens.add(kitten); } /** * @hibernate.property * column="SEX" * not-null="true" * update="false" */ public char getSex() { return sex; } void setSex(char sex) { this.sex=sex; }}</pre></div></div><div class="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="session-configuration.html">上一页</a> </td><td width="20%" align="center"><a accesskey="u" href="index.html">上一级</a></td><td width="40%" align="right"> <a accesskey="n" href="mapping.html">下一页</a></td></tr><tr><td width="40%" align="left" valign="top">第 3 章 SessionFactory配置 </td><td width="20%" align="center"><a accesskey="h" href="index.html">起始页</a></td><td width="40%" align="right" valign="top"> 第 5 章 O/R Mapping基础</td></tr></table></div></body></html>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -