级联更新未触发

时间:2015-05-16 13:46:46

标签: hibernate grails gorm

我有2个域类。 ParentDomain和Section。

class ParentDomain {
    String description
    List sections
    static hasMany = [sections:Section]
}



class Section {

    String name
    static belongsTo = [parentDomain : ParentDomain]
}

在我设置(第一次)parentDomain.setSections(节对象列表)时的服务方法中,它使用节表中的以下内容正确保存它。

+----+---------+---------------+-------------+------------------+
| id | version | name          | parentdomain_id | sections_idx |
+----+---------+---------------+-------------+------------------+
|  1 |       0 | Section 1     |           6     |        0     |
|  2 |       0 | Section 1     |           6     |       0      |
+----+---------+---------------+-----------------+--------------+

当我从DB获取/更新父域对象并设置新部分对象的列表parentDomain.setSections(新部分对象的列表)然后运行parentDomain.save(flush:true)时,它不会删除旧部分表中的对象除了旧的部分之外还添加了新的部分条目。

+----+---------+---------------+-------------+------------------+
| id | version | name          | parentdomain_id | sections_idx |
+----+---------+---------------+-------------+------------------+
|  1 |       0 | Section 1     |           6     |        0     |
|  2 |       0 | Section 2     |           6     |        1     |
|  3 |       0 | Section 3     |           6     |        0     |
|  4 |       0 | Section 4     |           6     |        1     |
+----+---------+---------------+-----------------+--------------+

据我所知,它应该只在更新时保留2个部分对象,并且由于级联更新而删除旧部分。同样奇怪的是,当我从db获取父域对象实例时,我只获得与之关联的最后2个部分对象。是因为sections_idx?

1 个答案:

答案 0 :(得分:1)

这种情况正在发生,因为您使用了在hasMany属性中添加数据的错误方法。您应该使用setSections()方法(addTo*),而不是使用addToSections()方法。

删除不是自动的(除非你是自动绑定(不确定这个List方案))。您必须使用removeFromSections()方法(removeFrom*)手动从父项中删除子对象。

修改_____________________________________________________________

我不知道这些方法的内部过程,但addToSections方法是一个简单的setter方法,它与表的状态无关。因此,在您的情况下,它再次从0列中的sections_idx开始独立于此,该索引已经存在(* _idx列是我们在hasMany中使用List时最重要的列,就像您的情况一样。它维护列表中子项的索引。)因此第二次在parentDomain.sections中有两个实例而不是四个。

虽然*addTo方法(GORM)有助于按_idx从表中查找新条目的索引。

并且setter无法删除父子关联,removeFrom*就是为了这个。