2011-10-27 2 views
1

У меня есть следующий класс домена в Grails:Grails - Предотвращение рекурсивных один-ко-многим

class TreeNode { 
    String name 
    String description 

    static hasMany = [childNodes: TreeNode] 
} 

Что самое идиоматический Grails способ гарантировать, что экземпляр TreeNode не может иметь себя как ребенок ? Могу ли я сделать это как ограничение в классе домена, или я должен писать собственный код в действии Save на TreeNodeController?

ответ

1

Сделайте это как пользовательское ограничение.

static constraints = { 
    childNodes(validator: {value, obj, errors-> 
     if(value.contains(obj) { 
     errors.rejectValue('childNodes', 'Cannot contain self') 
     } 
    } 
} 
1

Ответ зависит от того, насколько глубоко вы хотите проверить детей. Если вас беспокоят только ближайшие дети, то код @Tiggerizzy должен работать нормально.

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

  1. Если другие свойства в изменении узла, а не структура дерева, вы можете пропустить детей проверить проверку и сэкономить дополнительное время обработки при проверке.
  2. Если вы проверяете результаты из близкого или в корне дерева, то проверка всех дочерних элементов будет более длительным процессом для большого дерева, что приведет к большому количеству работы с базой данных. Выполняя эту работу в классе Service, вы получаете транзакционный характер службы, который откатывает любые изменения базы данных на необработанном Exception, например, в ситуации оптимистического блокирования с другим потоком.
Смежные вопросы