Я столкнулся с той же проблемой, но в моем случае может быть дублировано одно или несколько полей (имя пользователя или адрес электронной почты).Следовательно, org.hibernate.exception.ConstraintViolationException
недостаточно конкретен, чтобы сказать, вызвало ли выбрасывание этого исключения имя пользователя или адрес электронной почты и какое сообщение отображать в последствии.
Я только что посмотрел на danny.lesnik ответ но это не здорово, так как он просто перенаправляет на «выделенную» страницу.Предполагая, что вы просто перенаправляете на страницу, на которой был пользователь, вы избежите создания новой страницы, которую вы бы сказали.Однако я предполагаю, что у вас уже есть валидатор Spring , выполняющий некоторую работу по проверке формы.Вот почему в моем случае я решил просто выполнить проверку дублирования моих полей (имя пользователя и адрес электронной почты) в одном и том же месте (в Валидаторе).Похоже, более подходящее, согласованное (с остальной частью проверки) и более чистое решение.
Вот некоторый код для иллюстрации:
Мой контроллер
@Controller
public class WebController {
@Autowired
private UserServiceImpl userService;
@Autowired
private CustomUserDetailsValidator customUserDetailsValidator;
...
@RequestMapping(value = "/login/create-account", method = RequestMethod.POST)
public String createAccount(@ModelAttribute("user") CustomUserDetails user, BindingResult result, Model model, SessionStatus status) {
customUserDetailsValidator.validate(user, result);
if(result.hasErrors()){
model.addAttribute("user", user);
// Print the errors to the console - FIXME: log error instead
System.out.println("Validation errors:");
for (FieldError error : result.getFieldErrors()) {
System.out.println(error.getField() + " - " + error.getDefaultMessage());
}
return "login/create-account";
}
else{
userService.registerUser(user);
return "redirect:/login/create-account-success";
}
}
...
}
Мой валидатор
public class CustomUserDetailsValidator implements Validator {
@Autowired
private UserServiceImpl userService;
...
@Override
public void validate(Object target, Errors errors) {
// some simple validations
// and here some complex validation (is username or email used duplicated?)
if(errors.getAllErrors().size() == 0){
if ( userService.doesUsernameAlreadyExist( user.getUsername() ) )
errors.rejectValue(usernameFieldName, "duplicate.username","username already exists");
if ( userService.doesEmailAlreadyExist( user.getEmail() ) )
errors.rejectValue(emailFieldName, "duplicate.email","email already exists");
}
}
}
Я не уверен, что это лучший способ сделать это, но подумал, что мое решение позволит расширить его (вы можете добавить различные проверки для любого другого ограничения).
Надеюсьэто помогает другим, и было бы интересно узнать об этом решении больше разработчиков.