2016-06-10 2 views
2

Я использую Spring Boot (1.3.3.RELEASE) с данными Spring и Bean Validation в проекте, и я нашел неожиданное (по крайней мере для меня) поведение. У меня есть объект User и его UserRepository (интерфейс, расширяющий JpaRepository). Когда я делаю вызов так:Почему метод сохранения данных Spring Data JPA не подтвердился сразу?

userRepository.save(user); 
logger.info("User saved with id", user.getId()); 

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

Но если я изменяю:

userRepository.saveAndFlush(user); 
logger.info("User saved with id", user.getId()); 

ConstraintViolationException выбрасывается сразу и регистратор линия никогда не будет достигнута.

Это второе поведение, в котором исключение выбрасывается перед регистратором, является тем, что, я считаю, должно произойти, когда я вызываю метод userRepository.save().

Что не так? Что-то о моем проекте? Или мое понимание того, как должна работать проверка валика?

ответ

2

Я бы сказал, что запуск проверки с уровня доступа к данным - это плохой дизайн и принципиально плохая идея. В основном это означает, что весь код, который передал вам экземпляр для сохранения (и в конечном итоге сбой) и этот экземпляр, был нарушен (в недопустимом состоянии) все время. Если это не привело к провалу некоторых промежуточных бизнес-логик, пальцы скрещены!

Этот подход обычно работает для очень простых сценариев CRUD, поскольку в принципе посредник может не работать, если, например, поле null, но не должно быть и т. д. Но как только вы начнете добавлять некоторую логику между этими ошибками, вы уже нарушите свою логику (например, что-то ожидает, что адрес электронной почты будет иметь правильный формат, не равный нулю и т. д.), ,

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

JSR-303 затем может использоваться в слое, принимая потенциально испорченные пользовательские данные. Но это определенно то, что вы не должны использовать в своей модели домена.

1

В зависимости от вашей стратегии флеша и генератора идентичности фактическая вставка в БД может (и в вашем случае это произойдет) произойти позже. А в случае Hibernate он проверяется непосредственно перед вставкой/обновлением/удалением (которые в вашем случае отложены). См. Источники BeanValidationEventListener и его методы onPreInsert(), onPreUpdate() и onPreDelete().

Смежные вопросы