HibernateValidator 5, похоже, не выполняет каскадную проверку объектов JPA

У меня проблема с Hibernate и Hibernate Validator 5. У меня есть некоторая сущность, скажем Group и другая сущность Person. Они связаны следующим образом: Группа имеет две ссылки на Лицо - контактное лицо и менеджер. Они оба являются взаимно однозначными отношениями с полным каскадом и вариантами удаления сирот.

Я хочу подтвердить контактное лицо и менеджера во время сохранения группы. Более того, я хочу, чтобы для проверки контактного лица и менеджера использовалась другая группа проверки. Для этого я поместил @ConvertGroup(from = Default.class, to = ContactPersonValidation.class) вместе с @Valid перед полем контактного лица, и я сделал это аналогично для поля менеджера (используя другую группу проверки).

Теперь проверка Hibernate не работает - я имею в виду, что группа не преобразована в ту, которая указана в @ConvertGroup. Я следил за исходным кодом валидатора Hibernate, и, похоже, он проверяет объект Group и два объекта Person отдельно. Следовательно, проверка Person не передается каскадом из объекта Group, и группа проверки не преобразуется.

Вы когда-нибудь сталкивались с подобной проблемой и знаете, как ее решить?


person Jacek L.    schedule 08.11.2013    source источник
comment
Было бы полезно, если бы вы показывали фактические аннотированные объекты и то, как вы сохраняете / сохраняете объекты. Вы используете собственный сеанс Hibernate или JPA? Как вы проводите валидацию? Вы полагаетесь на валидацию на основе жизненного цикла?   -  person Hardy    schedule 08.11.2013
comment
Я использую собственный сеанс Hibernate и полагаюсь на проверку на основе жизненного цикла.   -  person Jacek L.    schedule 10.11.2013


Ответы (1)


Во время проверки жизненного цикла, запускаемой JPA, Bean Validation использует TraversableResolver, который не отслеживает ассоциации, даже если они помечены @Valid (см. 3.6.1.2 «Требования к автоматической проверке событий жизненного цикла» спецификации JPA 2.0).

Таким образом, ваши Person объекты не будут проверяться путем отслеживания ссылок из Group, но они будут проверены, когда сами будут сохранены. Таким образом, групповые преобразования, объявленные на Group, не применяются.

Вы можете реализовать желаемое поведение, определив GroupSequenceProvider для Person (обратите внимание, что это особенность валидатора Hibernate). Для этого вам нужно передать «роль» человека (например, в форме перечисления со значениями Contact и Manager) экземплярам Person. Затем поставщик последовательности групп по умолчанию может получить доступ к роли и применить ту или иную группу проверки, если данный экземпляр Person сохраняется.

person Gunnar    schedule 08.11.2013
comment
Я знаю, что он использует TraversableResolver и не поддерживает ассоциации. Я уже сделал это так, как вы описали (с использованием GroupSequenceProvider), но я надеялся, что есть какой-то трюк, чтобы сделать это лучше (или, возможно, чище) :) - person Jacek L.; 10.11.2013