Grails находит родителя рядом со многими

Моя проблема должна быть очевидной, но я просто не вижу света прямо сейчас :-(

У меня есть два доменных класса:

class Parent {
  String name
  static hasMany = [children: Child]
}

class Child {
  String name
}

Теперь я должен иметь возможность найти родителя ребенка, используя динамический поиск родителя, например:

Parent.findByChildren([someChild] as Set)

Но я получаю сообщение об ошибке спящего режима, в котором говорится, что у меня есть грамматическая ошибка в моем спящем режиме SQL:

Caused by: java.sql.SQLException: No value specified for parameter 1

И для справки: someChild ЯВЛЯЕТСЯ конкретным экземпляром. И я хотел бы, чтобы у Child не было явного родителя в определении.

Как же я могу перейти от Ребенка к Родителю?

Наилучшие пожелания,

Кристиан Сонне Дженсен


person Christian von Wendt-Jensen    schedule 29.06.2010    source источник


Ответы (4)


Чтобы закончить этот вопрос, я хотел сообщить о решении моей «проблемы». Я использую namedQuery в объекте Parent (Customer или Producer) следующим образом:

Class Customer {

  static hasMany = [channels: Channel]

  static namedQueries = {
   findByChannel {
        channelId ->
          channels {
              eq 'id', channelId
      }
    }
  }
}

Затем я нахожу Заказчика следующим образом:

def customers = Customer.findByChannel(channel.id).list()

Таким образом, канал освобождается от необходимости знать что-либо о том, кто на него ссылается, и мне не нужно делать никаких искусственных таблиц взаимосвязей.

Я все еще думаю, что это какая-то ошибка, что я не могу использовать один из динамических искателей:

Customer.findByChannels([channel] as Set)

Может быть, динамические искатели не учитывают отношения «один ко многим» и работают только для простых атрибутов ??? (Я использую Grails 1.3.1)

Спасибо за ваши ответы!

Кристиан Сонне Дженсен

person Christian von Wendt-Jensen    schedule 30.06.2010

Если вы не хотите использовать родительский внешний ключ для дочернего элемента, вам придется создать таблицу соединений для родителя, которая служит суррогатом для дочернего элемента:

class ParentalRelationship { 
    static belongsTo = [parent: Parent, child: Child]
}

Затем у вас могут быть вспомогательные методы для родительского объекта для запроса дочерних элементов через объект ParentalRelationship.

С вашей реальной реализацией Клиентов, Каналов и Производителей есть вероятность, что вам в любом случае понадобится отношение «многие ко многим», поскольку канал не будет принадлежать одному покупателю (или одному производителю).

person Ted Naleid    schedule 30.06.2010
comment
Grails управляет отношениями «многие ко многим», а также автоматически создает таблицы соединений. - person Pablo Pazos; 27.11.2016

Может быть, лучше написать в chield belongsTo что-то вроде этого:

static belongsTo = [parent: Parent]

И тогда вы можете использовать:

Chield c = ...
Parent parent = c.parent
person jotied    schedule 07.02.2012

Я бы инвертировал:

class Parent {
  String name

  static Set<Child> getChildren() {
    Child.findAllByParent(this) as Set
  }
}

class Child {
  String name
  Parent parent
}

При этом используется та же структура базы данных (дочерняя таблица имеет внешний ключ для родительской), но упрощается переход с одной стороны на другую без явной двунаправленности.

Меняется одно. Вместо этого:

def parent = ...
parent.addToChildren(new Child(...))
parent.save()

ты делаешь это:

def parent = ...
def child = new Child(parent: parent, ...).save()

Это более эффективно, потому что вам не нужно загружать всю коллекцию только для того, чтобы сохранить новый дочерний элемент.

person Burt Beckwith    schedule 29.06.2010
comment
Да, я думал об этом, но я хочу, чтобы Дитя не знало о своем родителе. В моем РЕАЛЬНОМ случае у меня есть клиент и канал как родитель и ребенок. У Заказчика есть список Каналов, но Канал также может быть отображен, например, Продюсером. Следовательно, Канал не должен знать о Потребителе (или Производителе), поскольку это сделало бы Канал менее общим. Это обычное явление, когда таблицы отображаются другими объектами без ведома таблиц. Мне просто нужно знать синтаксис перехода от дочернего (канала) к родительскому (заказчик/производитель/что угодно) С наилучшими пожеланиями - person Christian von Wendt-Jensen; 29.06.2010