Grails hasMany: найти все основные записи с дочерними элементами, которые соответствуют критериям.

У меня есть проект Grails 2.0.3, в котором есть две модели DomainA и DomainB, и обе связаны друг с другом отношениями many-to-many, в которых DomainB является дочерним элементом DomainA.

class DomainA {
  // properties
  static hasMany = [domains: DomainB]
}

class DomainB {
  // properties
  static hasMany = [domains: DomainA]
  static belongsTo = [DomainA]
}

Учитывая такой дизайн, я хочу запросить все DomainB, в которых есть экземпляр(ы) DomainA после запроса, установленного на DomainA.

def domainsList = DomainA.createCriteria().list() {
   // other criterions for the other properties
}
DomainB.createCriteria().list() {
   inList("domains", domainsList)
   // other criterions for the other properties
}

При выполнении приведенного выше кода возникает ошибка ERROR util.JDBCExceptionReporter - Parameter #1 has not been set., где Parameter #1 — это запрос имени свойства domains в критерии inList.

Имея такую ​​проблему, возможно ли это решить? Как?


person David B    schedule 02.08.2012    source источник
comment
У вас есть класс DomainA, определенный дважды. Вы можете исправить свой вопрос?   -  person ubiquibacon    schedule 02.08.2012
comment
Обновлено. Спасибо за уведомление.   -  person David B    schedule 02.08.2012
comment
Я думаю, что inList может быть неподходящим предикатом для этого: B.domains — это список, а не отдельный домен A, поэтому он в любом случае никогда не будет членом списка, состоящего из доменов As, верно?   -  person Ulrich Schwarz    schedule 02.08.2012
comment
Я думаю, что B.domains - это набор, а не список. Что касается свойств членов, я искал аналогичный вопрос здесь stackoverflow.com/questions/10429023/   -  person David B    schedule 02.08.2012


Ответы (2)


Взгляните на руководство по GORM и найдите "Запрос ассоциаций". Давайте лучше попробуем сделать все это с помощью одного запроса.

С новым запросом «где» это

def query = DomainB.where {
  domains { someAField == 3 } && someBField == 8
}

или с CriteriaBuilder:

DomainB.withCriteria {
  domains { 
    eq 'someAField', 3 
  }
  eq 'someBField', 8
}
person Victor Sergienko    schedule 02.08.2012

Вы можете использовать HQL:

def domainBsWithDomainAs = DomainB.executeQuery( 'SELECT DISTINCT b FROM DomainB b INNER JOIN b.domains a WHERE a IN(SELECT DISTINCT a FROM DomainA a)' )

Или с помощью createCriteria:

def domainsList = DomainA.createCriteria().list() {
   // other criterions for the other properties
}
DomainB.createCriteria().list() {
   "in"("domains", domainsList) // Use "in" (including quotes) instead of inList.
   // other criterions for the other properties
}
person ubiquibacon    schedule 02.08.2012
comment
Я планировал использовать HQL, но есть ли способы решить эту проблему с помощью HibernateCriteriaBuilder? - person David B; 02.08.2012
comment
Это было бы так, это только сказало бы, что нет экземпляра DomainA ни в одной записи DomainB. Что, если бы я создал HibernateCriteriaBuilder в DomainA и использовал его для запросов в DomainB. Обновил мой вопрос. - person David B; 02.08.2012
comment
Я думал, это то, чего ты хотел. Вы хотите использовать ключевое слово in. Вы должны прочитать createCriteria, там приведены примеры и списки ключевых слов, которые вы можете использовать. - person ubiquibacon; 02.08.2012
comment
Извините за изменение, но все же он возвращает мне то же сообщение об ошибке. Я попытался изменить свою базу данных с H2 на MySQL и MSSQL, все та же ошибка. Поддерживается ли функция Grails по-прежнему или я должен перейти на HQL? - person David B; 03.08.2012