Inheritance 如何在Grails/GORM中将域类模型对象从一个派生类更改为另一个派生类

Inheritance 如何在Grails/GORM中将域类模型对象从一个派生类更改为另一个派生类,inheritance,grails,gorm,table-per-hierarchy,Inheritance,Grails,Gorm,Table Per Hierarchy,给定以下Grails GORM域类并使用每个层次结构的表继承: class Book { static belongsTo = [ parent: Parent ] String title } abstract class Parent { static hasMany = [ books: Book ] } class A extends Parent { String asset } class B extends Parent { String asset }

给定以下Grails GORM域类并使用每个层次结构的表继承:

class Book {
  static belongsTo = [ parent: Parent ]
  String title
}

abstract class Parent {
  static hasMany = [ books: Book ]
}

class A extends Parent {
  String asset
}

class B extends Parent {
  String asset
}
假设我已从数据库中检索到类A的实例。我想将其转换为类B的实例。grails惯用的方法是什么

如果没有hasMany关系,我只想删除A并创建一个新的B。但是我不想因为浏览大量书籍和更新它们的父id字段而导致指向新B的开销


实际上,我只想执行一次SQL更新,将数据库字段parent.class从A更改为B。那么在GORM/Grails中,推荐的方法是什么呢?

Grails或Hibernate中不支持这一点,因为它类似于在内存中将A的实例更改为B,但对象具有固定类型,不能更改。无法直接访问需要更改其值的鉴别器列

因此,正如您所说,实现这一点的方法是通过SQL更新。有几个选项,但最好的可能是
groovy.sql.sql
,例如

import groovy.sql.Sql

class FooService {
   def dataSource

   void convertToB(A a) {
      def sql = new Sql(dataSource)
      sql.executeUpdate('update parent set class=? where id=?', [B.name, a.id])
   }
}

看起来像是设计缺陷的标志

您可以尝试用聚合替换继承--从
Parent
提取一个接口,例如,
HasAsset
,并添加对
HasAsset
的引用


可能会有帮助。

当然,上面的例子在这里发布时被大大简化了,因此失去了一些意义。这个问题的实质是用不同类型的条目替换具有特定ID的条目。也就是说,ID#5不再是A。现在它是B。你可以改变A的其他一切,为什么不改变类型?但是你对Groovy代表团的看法很好,谢谢你的建议。我明白你的意思,你明白我的意思吗?如果您希望更改所有内容,为什么要使用无法更改的语言元素(类继承)?你所需要的答案不是你所问问题的答案。我不是说你做的每件事都错了,只是注意到这可能是一个错误决策的迹象。我尝试了本机SQL,但在我的集成测试中它实际上不起作用。在运行本机SQL查询之后,我仍然在检索旧版本。我怀疑Hibernate的缓存与此有关。但我已经开始使用变通方法,而不是在数据库中用B替换a。就像你说的,这真的违背了GORM的初衷,结果花了太长时间。谢谢你的回复!