【问题标题】:Grails one-to-many delete without cascade没有级联的 Grails 一对多删除
【发布时间】:2013-08-21 02:18:17
【问题描述】:

我正在尝试在 Grails 中创建双向多对一关系,并在两个方向上进行非级联删除。我的域名如下所示:

class Asset {
  static hasMany = [ hosts: Host ]

  static mapping = {
      hosts cascade: 'save-update'
  }
}

class Host {
  Asset asset
}

这在删除主机时工作正常(资产仍然存在),但是当我尝试删除资产时,我从数据库中收到完整性约束错误。我尝试将 Host 类定义更改为使用 belongsTo,但无法使其正常工作。任何帮助都会很棒!谢谢!

【问题讨论】:

  • 你用的是什么数据库?
  • 尝试在Hostasset 属性上添加nullable: true
  • 我在本地开发人员上使用 hsqldb。我将其设置为 nullable:true 并且无法弄清楚为什么我仍然收到错误..
  • 您是否尝试删除“主机级联:'save-update'”并添加belongsTo?
  • 我尝试在 Host 上添加 belongsTo[asset:Asset] 并删除 Asset 中的级联定义,但在尝试删除 Asset 时仍然收到错误消息。

标签: hibernate grails grails-orm


【解决方案1】:

您有具有以下规则/属性的父(资产)和子(主机)类:

  1. 父母有孩子
  2. 没有父级,子级就无法存在(双向)
  3. 父级不能删除子级

您的困境是您希望能够删除 Parent - 但您将违反规则 #2。即使使用映射表,我认为您也无法按照您的要求进行操作。我从来没有遇到过这种用例,如果不重新设计你当前的模型太多,我猜你必须:

  1. 正如@JamesKleeh 指出的那样 - 允许在 Host.asset 上为空 - 基本上,儿童可以在没有父母的情况下存在
  2. 或允许父级删除子级(即级联删除)

【讨论】:

  • 我正在尝试获取您的解决方案 #1,但 nullable:true 仍然会导致错误消息。我设法让解决方案 #2 工作,但如果用户不小心删除了一个资产(分配了许多主机),这可能是一个问题。
【解决方案2】:

这是一个many-to-many 关系,在 GORM 中它实际上会按照您想要的方式工作:您可以将 hosts 添加到 Asset 所有者并安全地删除 Asset 而不会影响 hosts

【讨论】:

    【解决方案3】:

    我最终通过为资产控制器编写自己的 delete() 操作找到了解决方案,该操作在删除资产本身之前从所有主机中删除对资产的所有引用:

    def delete() {
        def assetInstance = Asset.get(params.id)        
        assetInstance.hosts.each { theHost ->
            theHost.asset = null
            theHost.save()
        }
        if(!assetInstance.hasErrors() && assetInstance.delete()) {
            redirect(action: "list")
        }
        else {
            redirect(url: "/asset/show?id=${assetInstance.id}")
        }
    }
    

    这消除了错误,并防止在删除父级(资产)时删除子级(主机)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-02-27
      • 1970-01-01
      • 2011-08-22
      • 2010-11-25
      • 1970-01-01
      相关资源
      最近更新 更多