Grails найти родителя многими сторонами - PullRequest
4 голосов
/ 29 июня 2010

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

У меня есть два типа классов:

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

class Child {
  String name
}

Теперь я должен быть в состояниинайти Родителя ребенка с помощью динамического поиска Родителя, например:

Parent.findByChildren([someChild] as Set)

Но я получаю сообщение об ошибке гибернации, утверждающее, что в моем спящем SQL-коде произошла ошибка грамматики:1010 *

И для справки: someChild - это конкретный экземпляр. И я бы хотел, чтобы у Child не было явного родителя в определении.

Как тогда я могу перейти от Child к Parent?

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

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

Ответы [ 4 ]

3 голосов
/ 30 июня 2010

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

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)

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

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

1 голос
/ 07 февраля 2012

Может быть, лучше написать chield belongsTo примерно так:

static belongsTo = [parent: Parent]

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

Chield c = ...
Parent parent = c.parent
1 голос
/ 30 июня 2010

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

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

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

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

0 голосов
/ 29 июня 2010

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

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()

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

...