【问题标题】:merge two domain objects and reassign children to one of them in Grails在 Grails 中合并两个域对象并将子对象重新分配给其中一个
【发布时间】:2011-05-31 20:35:15
【问题描述】:

我想要合并的域实体中有两个条目。让我们称父母之家和孩子之家。我有一种情况,我想合并两个实际上相同的 House 域。我有逻辑来做这个顶级合并。

但是,我想知道 Grails 中是否有一种方法可以轻松地说:“遍历域对象,只要有指向 House 的 fk 指针,就将该 fk 更新为新值”。

代码是这样的

houseInst1.magicMerge(houseInst2)

这将运行 House 合并,并检查每个具有指向 House 的指针 (fk) 的域对象,并将原来指向 houseInst2 的位置更新为指向 houseInst1。

更新:一个关键特性是,如果有人添加另一个域对象并带有指向主对象的链接,我希望它能够工作。例如。如果后来有人添加了 Mortgages,我不想更新我所有的合并逻辑,它应该去发现 Mortgages 是 House 的孩子,并相应地更新。

【问题讨论】:

    标签: grails groovy merge grails-orm


    【解决方案1】:

    Grails 域对象公开了 hibernate merge() 方法,但这完全不同:它将一个(可能是分离的)对象合并回持久化上下文中。

    我不知道有任何内置功能可以像您描述的那样合并两个对象。我认为您需要像 Gregg 的回答那样手动更新外键。一种更有效的更新方式是通过 HQL,如下所示:

    Room.executeUpdate('update Room set house = :newHouse where house = :oldHouse',
        [newHouse: newHouse, oldHouse: oldHouse])
    

    编辑:要自动更新所有关联,您可以询问 Artefact:

    def artefact = grailsApplication.getArtefact("Domain", "House")
    artefact.associationMap.values().each { associationClass ->
        associationClass.executeUpdate("update ${associationClass.simpleName} set house = :newHouse where house = :oldHouse",
            [newHouse: newHouse, oldHouse: oldHouse])
    }
    

    【讨论】:

    • 我做了一个更新,如果我知道这些关系,我就会知道如何做到这一点。我希望能够检查所有关系并更新 House 的所有孩子。这样可以减少维护。
    • 更新了我的答案以动态获取关联并在所有关联上更新house
    • 太棒了,我想这正是我想要的。即使 House 没有定义 hasMany,associationMap 是否有效?
    • 一个快速测试显示关联只有在定义了hasMany 关系时才会显示在关联映射中。如果您真的需要查找所有关联,包括那些没有声明关系的关联,您可以使用grailsApplication.getArtefacts("Domain") 获取所有域类工件并单独检查它们以获取House 类型的属性.
    【解决方案2】:

    这样的事情怎么样?在你摆脱旧房子之前,你会想要这样做。

    Room.findAllByHouse(oldHouse).each { room ->
        room.house = newHouse
        room.save()
    }
    

    我还没有尝试过,我假设 House 和 Room 之间存在相当标准的 OneToMany 关系。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-07-10
      • 1970-01-01
      • 2020-10-13
      • 2015-09-22
      • 2017-04-07
      • 2018-10-29
      • 2013-05-03
      • 2017-12-13
      相关资源
      最近更新 更多