As far as I know, the only way to do this is to create another domain class that represents the parent-child relationship.
class DimensionDependency { Dimension parent Dimension child static belongsTo = Dimension } class Dimension { static hasMany = [parentDependencies: DimensionDependency] static mappedBy = [parentDependencies: 'child'] static mapping = { parentDependencies cascade: 'all-delete-orphan' } }
The mappedBy indicate that an object related to DimensionDependency is always a child. By specifying all-delete-orphan in the mapping, we make sure that when parentDependency removed from the child, the associated DimensionDependency is deleted from the database.
You can also add convenience methods to your Dimension class to encapsulate operations on DimensionDependencies to make the interface more similar to GORM.
static transients = ['children', 'parents'] Set<Dimension> getChildren() { AssignmentDependency.findAllByParent(this).child } Set<Dimension> getParents() { parentDependencies?.parent ?: [] } Dimension addToParents(Dimension parent) { if (!parentDependencies.find { it.parent == parent && it.child == this }) { addToParentDependencies(new DimensionDependency(parent: parent, child: this)) } return this } Dimension removeFromParents(Dimension parent) { def dep = parentDependencies.find { it.parent == parent } removeFromParentDependencies(dep) dep.delete(flush: true) return this }
I have used this approach for some time and still have not worried.
source share