christopher
christopher

Reputation: 27346

Grails Hibernate criteria - Checking if a relation exists

I'm attempting to perform a filter to find if a certain object has a relationship with another. I had an object Component:

class Component { 
    long id
    String name
}

And a Component is used by a Page.

class Page {
    long id
    static hasMany = [components : Component]
}

How would I go about building a hibernate criteria to check if my component has a relationship with any page? One component can be used by many pages. So far, all I can think of is something like:

Component.createCriteria().list {
    inList("id", Page.list().components);
}

But that isn't going to scale very nicely at all. So I was wondering if there was a simpler way of saying "If my object is used by this object"?

Upvotes: 0

Views: 1884

Answers (3)

Sudhir N
Sudhir N

Reputation: 4096

You can use exists with a subquery.

def subQuery = Page.where({
   components {
      eqProperty("id", "this.id") //this: is the root alias which refers to the Component
   }
   setAlias("page")
})


Component.createCriteria().list {
  exists(subQuery.id())
}

See how to execute exists subqueries with grails criteria

Upvotes: 1

Yaro
Yaro

Reputation: 148

Another way is to create a PageComponent domain to match the underlying join table that was created by grails automatically and do PageComponent.countByComponentId(componentId)

Upvotes: 0

MKB
MKB

Reputation: 7619

Page.createCriteria().count {
    components {
        eq("id", yourComponent.id)
    }
}

This query gives you the count of all the Pages which have yourComponent. And if this is 0 then there yourComponent is not associated to any Page.

EDIT____________________________________________________________

No, because Component have no relation with Page.

But if you want this then my suggestion is formula column. In this relationship you have three tables component, page and there relationship table page_components.

eg.,

class Component { 
    long id
    String name
    Boolean isRelatedWithAnyPage

    static mapping = {
        isRelatedWithAnyPage formula: "(select (count(*)>0) from page_components pc where pc.component_id = id)"
    }
}

Note:- I haven't tried this, may be you need to change the sql query in formula.

Upvotes: 1

Related Questions