4.3.3管理auction categories

 

系统管理员可以创建新的categories,重命名categories,移除其子categories。你可以从图4.3中看到这种结构。

现在,我们来映射这个类和关联:

正如第三章讨论的,这是一个递归的、双向的一对多关联。one-valued的一端使用了<many-to-one>元素,Set类型则使用了<set>元素。它们都指向了同一个外键列:PARENT_CATEGORY_ID。

假设我们创建一个Computer的category,并且它作为一个子category出现,参见图4.4。

我们有几种方法来创建一个新的Laptops对象并且把它保存到数据库当中。

computer实例是已经持久化了的,它的childCategories关联也拥有cascade。因此,当tx.commit()的时候,laptops也会被保存,这要归功于Hibernate的脏数据检测。Hibernate会执行一个INSERT操作。

让我们再来重做一遍,不过这次创建的关联是在任何事务之外的。

处于detached状态的computer对象以及其他和computer关联的detached对象选择和处于transient的laptops对象产生了关联。我们通过另外一个session来持久化这种变化:

Hibernate会检测laptops的父category的数据库标识符属性从而正确的在数据库中创建和Computer的关联。Hibernate会把父category的值作为外键插入到Laptops行。

因为cascade=”none”在parentCategory关联中的设定,Hibernate会忽略任何其他categories的关联。如果我们在<many-to-one>中指定了cascade=”save-update”,那么Hibernate会将内存中所有关联的对象保持和数据库同步。这样的可操作性并不好,因为太多无用的数据会被请求到。在这个例子中,对于parentCategory关联并不需要传播性的持久化。

为什么我们需要cascading操作?我们可以像之前的例子那样保存laptop对象而不需要任何关于cascade的映射。那么请考虑下面的例子:

在上面的例子中,你需要单独的存储每个新的category。但是,如果我们在childCategories关联中设置了cascade=”save-update”的话,我们就不需要这么麻烦的操作。我们只需要在session中保存一个单独的Laptops对象:

你可能会想为什么使用cascade=”save-update”而不是cascade=”save”。那么请考虑下面的例子,假设之前我们已经保存三个新的categories:

我们为Laptops增加了一个新的category,并且修改了三个已经存在的category。下面的代码会把这些变化发送到数据库中:

指定cascade=”save-update”会准确的反应以上这些变化。在这个例子中,它会更新三个detached对象,并且保存新的子category。

注意到最后一个代码示例仅仅在调用方法的方法和之前的两个例子不同。它使用了update()而不是save(),因为laptops已经被持久化了。

我们也可以使用saveOrUpdate()方法重写所有的例子:

saveOrUpdate方法则告诉Hibernate如果一个对象是transient的话,那么插入到数据库,如果是一个detached对象,则更新到数据库。从另一方面说,它做了和cascade=”save-update”相同的事情。

最后一个问题:Hibernate如何知道那个子category是detached,而那个又是transient的呢?

 

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