I am using spring and Hibernate in my application,There is one scenario where i insert same records morethan once ,So application correctly throwing Constraint Exception because i applied Unique constraint in one of the db column.So far is everything fine.
But i have to display some custom message like "record already exists'" instead of showing Hibernate Exception.
How can i do with Spring framework.
Any hints or examples greatly appreciated.
Regards,
Raju
Yes you can exception in controller:
@ExceptionHandler(Exception.class)
public ModelAndView handleMyException(Exception exception) {
ModelAndView mv = new ModelAndView("error");
mv.addObject("message"."record already exists");
return mv;
}
Of cause you can catch any tpe of exception just insert it as the parameter to @ExceptionHandler
Hope it helps.
I am facing the same issue but in my case either one or several fields can be duplicated (username or email). Hence the org.hibernate.exception.ConstraintViolationException
is not specific enough to say whether the username or email caused this exception to be thrown and what message to display in consequence.
I just looked at danny.lesnik's answer but it's not great as it simply redirects to a "dedicated" page. Assuming you simply redirect to the page user was on would avoid the creation of a new page you'd say. However I assume you already have a Spring validator doing some form validation work. That's why in my case I decided to simply do my fields (username and email) duplication checks in the same place (in the Validator). Seems like a more suitable, consistent (located with the rest of the validation) and cleaner solution.
Here is some code to illustrate:
My Controller
@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";
}
}
...
}
My Validator
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");
}
}
}
I'm unsure if that's the best way to do this but thought my solution would allow more extension (you can add various checks on any other constraint).
Hope it helps others and it'd also be interesting to get more devs' thought on this solution.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With