12

这个问题分为两部分,第一部分是关于清除列表,第二部分是关于将所有者分配给对象。

我在 Grails 的模型中的两个域对象之间存在一对多的关系。关系看起来是这样的……

class Person {

    static hasMany = [authorities: Role, locations: Location]
}

class Location {

    static belongsTo = Person

}

在我的应用程序中,locations列表Person完全刷新并替换为用户操作的新列表。更重要的是,我得到了Location独立于关联的对象列表Person。我通过检索当前登录的用户来解决将它们应用到哪个人,我称之为activePerson并且对我的目的来说很好。

我想要做的是删除所有现有位置activePerson并插入所有新位置,将它们与activePerson我去的时候相关联。我有一堆属性Person,此时我不想在这些属性上保留,所以我想避免仅仅因为位置子对象发生变化而保存整个父对象。

我想过遍历activePerson.locations列表并一个一个地删除它们,并依靠 GORM/Hibernate 将查询批处理在一起并在最后刷新。这似乎是蛮力,尽管它可能有效。我期待有一种clearLocations方法或类似的方法,但我找不到。

如果我只是用activePerson.locations新列表替换 并调用activePerson.save(flush:true),GORM 会处理现有行的删除吗?

其次,我想将新Location对象放到activePerson. 我可以再次填充activePerson.locations并保存整个内容,但如果可以的话,我想避免这种情况。我可以单独保存它们,但是我如何belongsTo在每个Location对象上进行设置?

回顾一下:

  1. 如何在一对多集合的多端清除列表?
  2. 如何将独立对象与父对象关联并单独保存它们?

谢谢

4

4 回答 4

10

清除Collection方法对我不起作用:

activePerson.locations.clear()

ConcurrentModificationException只需尝试通过调用避免迭代集合collect()

activePerson.locations.collect().each {
    item.removeFromLocations(it)
}

然后保存实体以执行 SQL 语句:

activePerson.save flush:true

链接到文章阅读更多: http ://spring.io/blog/2010/07/02/gorm-gotchas-part-2/

于 2013-10-27T03:18:05.643 回答
9

对于#1,您可以清除集合(默认为 Set):

activePerson.locations.clear()

对于 #2 使用 addToLocations:

activePerson.addToLocations(location)

当您保存人时,位置<->人的关系将被更新。

于 2010-01-15T17:24:07.177 回答
8

虽然这是一个较老的问题,但我遇到了一个非常相似的情况,我想更新一组子记录。以下是我选择解决它的方法。为简单起见,我将使用与提问者相同的对象/关系名称。

  1. mapping父域的块中,添加:

    static mapping = {
        locations(cascade: "all-delete-orphan")
    }
    
  2. 在子域中,添加@EqualsAndHashCode注释(以防万一还有另一个潜伏,我指的是groovy.transform.EqualsAndHashCode)。

  3. 使用 GrailsaddTo方法(例如addToLocations)将所有子元素添加到父域,然后保存父域。

虽然这种方法确实需要保存父域(提问者不想这样做),但考虑belongsTo到模型中的明确定义,这似乎是最合适的方法。因此,我会像这样回答提问者的编号问题:

  1. 与其手动执行,不如让 Grails/Hibernate 通过指定all-delete-oprhan关系上的级联行为来清除记录。

  2. 不要尝试直接保存子记录,而是保存父对象以匹配 Grails 似乎期望的内容。

于 2014-05-27T20:47:22.267 回答
0

这对我有用:

activePerson.locations.clear()
activePerson.properties = params

...

activePerson.save()

这会清除一组位置,然后只添加当前在 params 中选择的位置。

于 2019-04-24T19:55:24.517 回答