简体   繁体   中英

Grails domain class containing itself

I'm trying to implement Subpage domain class in Grails and I would like to have Subpage with possibility of storing another Subpage. I was reading this and this post but none of these solutions seems to work for me.

My class looks like this:

class Subpage implements Comparable{

    String title
    Integer orderOfSubpage
    SortedSet subpageChild

    static hasMany = [component: Component, subpageChild: Subpage]
    static belongsTo = [domain: Domain, subpageParent: Subpage]

    static constraints = {
        orderOfSubpage nullable:false;
        subpageParent nullable:true;
        subpageChild nullable:true;
    }

        @Override
    public int compareTo(Object o) {
        if (this.orderOfSubpage > o.orderOfSubpage) {
            return 1;
        } else if (this.orderOfSubpage < o.orderOfSubpage) {
            return -1;
        }   
        return 0;
    }
}

According to the implementation, I was expecting Hibernate to create additional table with children, but I've looked into the database and the only one "mention" about Subpages of Subpages is SUBPAGE_PARENT_ID column in the SUBPAGE table. Using solution like this, I would have to iterate over whole table to get all children, I guess (or I miss something...).

Coming to the point: How do I have to implement this to get a Subpage class with possibility to get all children?

Thanks in advance.

I've taken your Domain and modified a couple of things. I omitted the compareTo method for brevity. Note that SortedSet subpageChild is not needed. It is already a SortedSet. I also renamed it to subpageChildren because it should be plural.

class Subpage implements Comparable{

    String title
    Integer orderOfSubpage

    static hasMany = [component: Component, subpageChildren: Subpage]
    static belongsTo = [domain: Domain, subpageParent: Subpage]

    static constraints = {
        orderOfSubpage nullable:false;
        subpageParent nullable:true;
        subpageChild nullable:true;
    }
}

So let's take a look at some code:

def subpage = new Subpage(title: "Subpage 1", orderOfSubpage: 1)
def child1 = new Subpage(title: "Subpage child 1", orderOfSubpage: 1)
def child2 = new Subpage(title: "Subpage child 2", orderOfSubpage: 2)
subpage.addToSubpageChildren(child1)
subpage.addToSubpageChildren(child2)
subpage.save()

We've created a subpage with 2 children. Now, let's see what a query looks like:

def subpage = Subpage.findByTitle("Subpage 1")

Now, let's iterate over its children

subpage.subpageChildren.each { child ->

}

That's basically it. Only 1 table needed.

You're basically creating a tree structure - there is already an answer on this here.

Tree structure in GORM (grails)

Just as an aside I would just have a single "Page" domain class and use the naming subpage/subpages to reference the children.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM