Композиция в Grails: addTo * в Конструкторах - PullRequest
2 голосов
/ 07 мая 2010

У меня есть следующая упрощенная модель в Grails:

  • A DataBlock состоит из нескольких отсортированных ConfigPreset объектов.

В ConfigPreset у меня есть

static belongsTo = [dataBlock: DataBlock]

и класс DataBlock содержит:

List presets
static hasMany = [presets: ConfigPreset]

DataBlock() {
    addToPresets(new ConfigPreset())
}

Перегруженный конструктор возвращает: Нет сигнатуры метода: [...]. AddToPresets () применим для типов аргументов: (ConfigPreset) значения: [ConfigPreset: null].

Но почему мой экземпляр ConfigPreset равен нулю? Если я пытаюсь создать объект DataBlock, например, BootStrap.groovy с неизмененным ctor и вызовом addToPresets (...) на нем, все работает.

Ответы [ 2 ]

1 голос
/ 07 мая 2010

Grails создает экземпляры классов вашего домена (и других артефактов) хотя бы один раз при запуске для своего кода инициализации. Это происходит до добавления динамических методов, отсюда и исключение. Он работает в BootStrap, так как на этом этапе все настроено. Обратите внимание, что ничто не является нулевым - вы просто видите toString () класса домена, который печатает имя и идентификатор, и, поскольку это новый экземпляр, идентификатор равен нулю.

Вы можете использовать обратный вызов beforeInsert для этого, смотрите - http://grails.org/doc/latest/guide/5.%20Object%20Relational%20Mapping%20%28GORM%29.html#5.5.1%20Events%20and%20Auto%20Timestamping

0 голосов
/ 07 мая 2010

Ваш пример не может работать.

Указание static belongsTo = [dataBlock: DataBlock] внутри ConfigPreset означает, что вы не можете создать экземпляр ConfigPreset без указания владельца DataBlock.

Так что в основном следующее утверждение

new ConfigPreset() всегда будет возвращать null в отличие от

new ConfigPreset(dataBlock: aDataBlock), который вернет действительный экземпляр ConfigPreset.

Метод addToXXX в основном делает следующее:

  1. Создать экземпляр XXX (как описано ниже)
  2. Добавить вновь созданный экземпляр XXX в this экземпляр

В вашем случае он не может создать ConfigPreset (шаг 1), так как экземпляр DataBlock еще не создан (вы находитесь в конструкторе)

Если вы хотите автоматически связывать ConfigPreset всякий раз, когда вы создаете DataBlock, вы можете сделать это с помощью Gorm Events, добавив callbalck к beforeInsert event.

Или вы можете удалить belongsTo и new ConfigPreset() будет работать.

...