Grails — ассоциации, ссылающиеся только на id

#grails #domain-driven-design

#grails #дизайн, управляемый доменом

Вопрос:

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

Человек

 class Person {

  Integer age

  String name

}
  

и телефонная афиша

 class PhoneBill {

  // reference to Person
  Long accountHolderId

  BigDecimal amount

}
  

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

Комментарии:

1. Используйте миграции базы данных и управляйте своими ограничениями внешнего ключа оттуда. Поскольку вы не моделируете свои отношения с использованием доменных классов GORM / Grails, теперь это зависит от вас.

2. Это то, что я изначально планировал, я просто не знал (на самом деле забыл) о миграции базы данных. Недостатком этого, я думаю, является то, что это немного затрудняет изменение хранилища данных, особенно для типов NoSQL. Это верно?

3. Зачем вам использовать хранилище данных NoSQL для реляционных данных? Это лучше всего поместить в СУБД. Я не уверен, работает ли плагин миграции базы данных с другими СУБД.

4. Есть много причин использовать NoSQL в качестве альтернативы базам данных SQL, даже для таких данных, как эти.

5. Справедливо, мой комментарий был просто для того, чтобы убедиться, что вы изучили все варианты и основали свой выбор на причине, а не просто на шумихе. Я полностью осознаю, что существует множество хороших вариантов использования баз данных NoSQL, но слишком часто люди просто используют их, не имея на то веской причины. (:

Ответ №1:

Предполагая, что у вашего Person объекта все еще есть идентификатор, вы можете добавить пользовательский валидатор, который возвращает ошибку, если значение id недопустимо.

 class PhoneBill {

  // reference to Person
  Long accountHolderId

  BigDecimal amount

    static constraints = {
        accountHolderId validator: { 
            !Person.exists(it) ?: 'your.custom.error.message.key'
        }
    }
}
  

.exists() Я полагаю, это доступно только для Grails 2.3.x. Если вы используете более старую версию, вы также можете вызвать .get() .

Комментарии:

1. Это кажется лучшим вариантом, чем подход миграции: 1) это выглядит легко протестировать (утверждение в DDD); 2) ограничение выражается в классе домена; 3) не создает проблем при изменении хранилища данных.

2. Хорошее решение, если вы можете гарантировать, что для доступа к данным используется только ваш домен, и кто-то не получает доступ к данным напрямую из хранилища данных, внешней системы / процесса.

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