0

Based this GORM Domain class:

class Component implements Serializable {
    Long id
    String name
    Double total
    Long parentComponentId

    static mapping = {
        ...
    }

    static constraints = {
        ...
        parentComponentId nullable: true
    }
}

My questions are:

  1. How do we reference a Domain class to itself, on this case parentComponentId is another instance of Component.
  2. If that referencing problem in #1 is solved, how can I execute a query similar to this:

    select a.*, b.* from COMPONENT a join COMPONENT b on a.id = b.parentComponentId group by a.id having sum(b.total) = a.total

Gideon
  • 1,469
  • 2
  • 26
  • 57
  • Have a bit of a look here: http://stackoverflow.com/questions/17653567/how-to-implement-self-referencing-relationships-in-grails. Seems like you should replace the `Long` property with a `Component` one. – zoran119 Aug 05 '15 at 06:34

2 Answers2

1

Just change the Long parentComponentId to Component parentComponent. You also don't need the Long id property, as grails add it for you:

class Component implements Serializable {
    String name
    Double total
    Component parentComponent

    static constraints = {
        parentComponent nullable: true
    }
}

Then you can access both the parent component and the parent component id:

assert Component.read(1).parentComponentId == Component.read(1).parentComponent.id

If you want to have cascade deletes, you'll need to remove the parentComponent property and add:

static hasMany = [nestedComponents: Component]
static belongsTo = [parentComponent: Component]

I'm assuming you have a 0:N relationship, if not you'll need to change that. Check the documentation for defining associations.

As for your second question, sadly you can't use having in a criteria yet: https://jira.grails.org/browse/GRAILS-7880

You can do it with HQL though:

Component.executeQuery("""
   select parent from Component parent, Component nested
   where nested.parentComponent = parent
   group by parent
   having parent.total = sum(nested.total)
""".toString())
Deigote
  • 1,721
  • 14
  • 15
0

You can do like this for first question.

class Component implements Serializable {
    Long id
    String name
    Double total
    static belongsTo = [parentComponentId:Component]
    static mapping = {
        ...
    }

    static constraints = {
        ...
        parentComponentId nullable: true
    }
}
praveen_programmer
  • 1,072
  • 11
  • 25