2010-03-16 2 views
4

У меня есть разочаровывающая проблема с построением критериев. У меня есть приложение, в котором один пользователь имеет один календарь, а календарь имеет много записей. Кажется достаточно простым, но когда я пытаюсь получить записи календаря для данного пользователя, я не могу получить доступ к свойству пользователя (MissingMethodException). Вот код:Grails: проблема с вложенными ассоциациями в построителе критериев

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

Я даже попробовал следующий вариант:

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

Это не вызывает исключение, но не работает.

Вот соответствующие части классов домена:

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

    ... 
} 

class User { 
    Calendar calendar 

    ... 
} 

class Entry { 
    static belongsTo = [calendar: Calendar] 

    ... 
} 

Когда Googling я наткнулся на аналогичной проблемой было отмечено в начале 2008 года: http://jira.codehaus.org/browse/GRAILS-1412

Но, по этой ссылке эта проблема должна быть решена давно.

Что я делаю неправильно?

+0

Вы можете включить org.hibernate.SQL отладки Loging и посмотреть, что запрос он работает?Это может помочь выяснить, что происходит не так. – leebutts

+0

Я пробовал, что я получил: Q1: выберите this_.id как id8_0_, this_.version as version8_0_, ... от пользователя this_ where this_.username =? Q2: выберите верх? count (*) as y0_ from entry this_ left внешний календарь календаря calendar_a1_ on this_.calendar_id = calendar_a1_.id где ((calendar_a1_.id =?)) Q3: выберите верхний? this_.id как id3_1_, this_.version как version3_1_, ... from entry this_ left external join calendar calendar_a1_ on this_.calendar_id = calendar_a1_.id где ((calendar_a1_.id =?)) Это кажется мне прекрасным , Есть идеи? (Извините за форматирование, комментарии, похоже, не очень хорошо относятся к коду.) –

+0

Я ничего не вижу о 'where calender.user_id =?' хотя ... – leebutts

ответ

9

Я наконец-то нашел ошибку !! Ошибка не была связана с построением критериев. Проблема в этом случае было то, что я имел пользовательскую переменную в объеме, поэтому, когда я пытался войти в связь пользователя с

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

Grails подумал, что я хотел назвать объект пользователя/переменную с закрытием. Я могу снова использовать критерии строителей свободно :-)

Спасибо за вашу помощь и предложения, ребята!

+1

радость интернета. Через 6 лет этот вопрос спас меня так много времени отладки. – user2782001

1

Я не уверен, почему ваши критерии не работают. У меня всегда были проблемы с тем, чтобы они работали совершенно правильно и находили их более странно, чем HQL.

Вы можете просто использовать HQL для своего запроса, который я считаю более естественным для написания и более легким для синтаксического анализа, так как я привык смотреть в SQL.

Вот ваш запрос в HQL:

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

Спасибо Теду, я бы предпочел, чтобы у меня были критерии, так как я думаю, что они более читабельны и проще в рефакторе. Но я буду использовать HQL в то же время, но это беспокоит меня, что строитель критериев не работает. –

0

Вот вещь

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

жаль, что я ошибся раньше, конечно, должно быть eq («id», user.id) , но это тоже не сработало, я все равно получаю ту же ошибку ... –

0
def entries = Entries.createCriteria().list() { 

Почему ты написал Записи? Ваше имя класса: Запись. Так я бы сказал, ваша линия следует читать:

def entries = Entry.createCriteria().list() { 
+0

Вы правы, еще один опечаток из моего часть. Howerver, это все еще не исправляет мою проблему :-( –

3

Если у вас есть такие ошибки объема, как плакат вопроса, вы всегда можете сделать следующее. Допустим, у вас есть переменная пользователя в Вашей области, а затем использовать

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

вместо

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