Grails: проблема с вложенными ассоциациями в построителе критериев

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

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]

    ...
}

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

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

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


person Mr.B    schedule 16.03.2010    source источник
comment
Можете ли вы включить ведение журнала отладки org.hibernate.SQL и посмотреть, какой запрос он выполняет? Это может помочь отследить, что происходит не так.   -  person leebutts    schedule 17.03.2010
comment
Я попробовал это, что я получил: Q1: выберите this_.id как id8_0_, this_.version как version8_0_, ... от пользователя this_ где this_.username=? Q2: выберите верх? count(*) as y0_ from the entry this_ left external join calendar calendar_a1_ on this_.calendar_id=calendar_a1_.id где ((calendar_a1_.id=?)) Q3: выбрать верхний? this_.id как id3_1_, this_.version как version3_1_, ... из записи this_ левого внешнего календаря соединения calendar_a1_ on this_.calendar_id=calendar_a1_.id где ((calendar_a1_.id=?)) Мне кажется, это нормально. Есть идеи? (Извините за форматирование, комментарии, похоже, не очень хорошо обрабатывают код.)   -  person Mr.B    schedule 17.03.2010
comment
Я ничего не вижу о том, «где calender.user_id =?» хоть...   -  person leebutts    schedule 20.03.2010
comment
Мне это кажется правильным. Я бы создал простой проект, используя ваши классы, и прикрепил бы его к новой ошибке JIRA.   -  person leebutts    schedule 20.03.2010


Ответы (5)


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

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

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

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

person Mr.B    schedule 01.11.2010
comment
радость интернета. 6 лет спустя этот вопрос сэкономил мне ТАК много времени на отладку. - person user2782001; 16.12.2016

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

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

вместо

def user = User.get(...)
...
calendar {
  user {
    eq("id", user.id)
  }
}
person codewandler    schedule 01.09.2014

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

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

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

Entry.executeQuery("from Entry e where e.calendar.user.id = :userId", [userId: theUser.id])
person Ted Naleid    schedule 17.03.2010
comment
Спасибо, Тед, я бы предпочел иметь критерии, так как я думаю, что они более читабельны и их легче рефакторить. Но пока я буду использовать HQL, но меня беспокоит, что построитель критериев не работает. - person Mr.B; 17.03.2010

Вот вещь

def getEntries(User user) {
 def entries = Entries.createCriteria().list() {
          calendar { 
             user { 
              eq("id", user.id)
             }
          } 
      }  
}
person Amit Jain    schedule 17.03.2010
comment
извините, я допустил ошибку ранее. Конечно, это должно быть eq (id, user.id), но это тоже не сработало, я все еще получаю ту же ошибку... - person Mr.B; 17.03.2010

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

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

def entries = Entry.createCriteria().list() {
person Adi    schedule 24.10.2010
comment
Вы правы, еще одна опечатка с моей стороны. Однако это все еще не решает мою проблему :-( - person Mr.B; 26.10.2010