How to change a Domain Class model object from one derived class to another in Grails/GORM

筅森魡賤 提交于 2019-12-08 01:59:24

问题


Given the following Grails GORM Domain Classes and using table-per-hierarchy inheritance:

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
}

Say I have retrieved an instance of class A from the database. I want to convert it to an instance of class B. What is the grails idiomatic way to do this?

Without the hasMany relation, I would just delete A and create a new B. But I don't want the overhead of going through a large number of Books and updating their parent_id fields to point to the new B.

Under the hood, I essentially just want to perform an SQL UPDATE to change the database field parent.class from A to B. So what's the recommended way to do this in GORM/Grails?


回答1:


There's no support for this in Grails or Hibernate, since it's the analogue of changing an instance of A to a B in-memory, but an object has a fixed type and cannot change. There's no direct access to the discriminator column that you need to change the value of.

So the way to do this is via a SQL update as you say. There are a few options but the best is probably groovy.sql.Sql, e.g.

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])
   }
}



回答2:


Looks like a sign of design flaw.

You could try to replace inheritance with aggregation - "Favor object composition over class inheritance." (Gang of Four 1995:20)" - extract a, say, HasAsset interface from Parent and add a reference to HasAsset.

Groovy delegation could help.



来源:https://stackoverflow.com/questions/5725362/how-to-change-a-domain-class-model-object-from-one-derived-class-to-another-in-g

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!