Question

I have a frustrating problem with the criteria builder. I have an application in which one user has one calendar, and a calendar has many entries. Seems straightforward enough, but when I try to get the calendar entries for a given user, I can't access the user property (MissingMethodException). Here's the code:

def getEntries(User user) {
  def entries = [ClassName].createCriteria().list() {
    calendar {
      user {
        eq("id", user.id)
      }
    }
  }
}

I have even tried the following variation:

def getEntries(User user) {
  def entries = [ClassName].createCriteria().list() {
    calendar {
      eq("user", user)
    }
  }
}

That did not raise an exception, but didn't work either.

Here's the relevant parts of the domain classes:

class Calendar {
    static belongsTo = [user: User]
    static hasMany = [entries: Entries]

    ...
}

class User {
    Calendar calendar

    ...
}

class Entry {
    static belongsTo = [calendar: Calendar]

    ...
}

When Googling I came across a similar problem noted in early 2008: http://jira.codehaus.org/browse/GRAILS-1412

But according to that link this issue should have been solved long ago.

What am I doing wrong?

Was it helpful?

Solution

I finally found the error!! The error wasn't at all related to criteria builder. The problem in this case was that I had user variable in the scope, so when I tried to enter the user relation by

calendar {
  user {
    eq("id", user.id)
  }
}

Grails thought that I wanted to call the user object/variable with a closure. I can once again use criteria builders freely :-)

Thanks for all your help and suggestions guys!

OTHER TIPS

If you have such scope errors like the poster of the question, you always can do the following. Lets say you have a user variable in your scope, then use

def user = User.get(...)
...
calendar {
  'user' {
    eq("id", user.id)
  }
}

instead of

def user = User.get(...)
...
calendar {
  user {
    eq("id", user.id)
  }
}

I'm not sure why your criteria isn't working. I've always had some problems getting them to work quite right and find them more fiddly than HQL.

You could just use HQL for your query, which I find more natural to write and easier to parse since I'm used to looking as SQL.

Here's your query in HQL:

Entry.executeQuery("from Entry e where e.calendar.user.id = :userId", [userId: theUser.id])

Here is a thing

def getEntries(User user) {
 def entries = Entries.createCriteria().list() {
          calendar { 
             user { 
              eq("id", user.id)
             }
          } 
      }  
}
def entries = Entries.createCriteria().list() {

Why did you wrote Entries? Your Classname is Entry. So i would say your Line should read:

def entries = Entry.createCriteria().list() {
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top