Necesito mostrar mensajes personalizados en mi aplicación Spring 3.0. Tengo una base de datos con Hibernate y hay varias limitaciones. Tengo dudas sobre cómo se debe manejar el DataIntegrityViolationException
de una buena manera. Me pregunto si existe una forma de mapear la excepción con un mensaje establecido en un archivo de propiedades, ya que es posible en la validación de Restricciones. ¿Podría manejarlo automáticamente de cualquier manera o tengo que atrapar esta excepción en cada controlador?Cómo manejar DataIntegrityViolationException en Spring?
Respuesta
El problema al mostrar mensajes fáciles de usar en el caso de una violación de restricción es que el nombre de la restricción se pierde cuando se traduce el ConstraintViolationException
de Hibernate al DataIntegrityViolationException
de Spring.
Sin embargo, puede personalizar esta lógica de traducción. Si usa LocalSessionFactoryBean
para acceder a Hibernate, puede suministrarlo con un SQLExceptionTranslator
personalizado (consulte LocalSessionFactoryBean.jdbcExceptionTranslator
). Este traductor de excepciones puede traducir un ConstraintViolationException
en su propia clase de excepción, conservando el nombre de la restricción.
El resorte 3 proporciona dos formas de manejar esto: HandlerExceptionResolver
en beans.xml, o @ExceptionHandler
en su controlador. Ambos hacen lo mismo: convierten la excepción en una vista para renderizar.
Ambos están documentados here.
trato a DataIntegrityViolationException
en ExceptionInfoHandler
, encontrando limitaciones DB ocurrencias en mensaje de causa raíz y la convierten en mensajes i18n través constraintCodeMap
:
@ControllerAdvice(annotations = RestController.class)
@Order(Ordered.HIGHEST_PRECEDENCE + 5)
public class ExceptionInfoHandler {
@Autowired
private MessageSource messageSource;
private static Map<String, String> constraintCodeMap = new HashMap<String, String>() {
{
put("users_unique_email_idx", "exception.users.duplicate_email");
put("meals_unique_user_datetime_idx", "exception.meals.duplicate_datetime");
}
};
@ResponseStatus(value = HttpStatus.CONFLICT) // 409
@ExceptionHandler(DataIntegrityViolationException.class)
@ResponseBody
public ErrorInfo conflict(HttpServletRequest req, DataIntegrityViolationException e) {
String rootMsg = ValidationUtil.getRootCause(e).getMessage();
if (rootMsg != null) {
Optional<Map.Entry<String, String>> entry = constraintCodeMap.entrySet().stream()
.filter((it) -> rootMsg.contains(it.getKey()))
.findAny();
if (entry.isPresent()) {
e=new DataIntegrityViolationException(
messageSource.getMessage(entry.get().getValue(), null, LocaleContextHolder.getLocale());
}
}
return new ErrorInfo(req, e);
}
...
}
se puede simular en mi Java Enterprise training application añadiendo/usuario de edición con el correo duplicado o una comida con dateTime duplicado.
ACTUALIZACIÓN:
otra solución: usar Controller Based Exception Handling:
@RestController
@RequestMapping("/ajax/admin/users")
public class AdminAjaxController {
@ExceptionHandler(DataIntegrityViolationException.class)
public ResponseEntity<ErrorInfo> duplicateEmailException(HttpServletRequest req, DataIntegrityViolationException e) {
return exceptionInfoHandler.getErrorInfoResponseEntity(req, e, EXCEPTION_DUPLICATE_EMAIL, HttpStatus.CONFLICT);
}
- 1. ¿Cómo podemos resolver la DataIntegrityViolationException en Spring Hibernate?
- 2. ConstraintViolationException VS DataIntegrityViolationException
- 3. incapaz de atrapar DataIntegrityViolationException con la transacción envuelta
- 4. Cómo manejar la eliminación RESTful en Spring MVC
- 5. ¿Cómo manejar llamadas internas en Spring/EJB/Mockito ... proxies?
- 6. ¿Cómo debo manejar las excepciones comprobadas en JavaConfig de Spring?
- 7. ¿Cómo manejar la sesión expirada utilizando spring-security y jQuery?
- 8. ¿Dónde y cómo manejar las excepciones spring + hibernate?
- 9. Traducir PersistenceException a DataAccessException en Spring
- 10. ¿Cómo manejar el error de conexión de Spring Webservice en la puesta en marcha?
- 11. ¿Cómo se configura Spring HandlerExceptionResolver para manejar NullPointerException arrojado en jsp?
- 12. ¿Cómo manejar múltiples subdominios por separado en una aplicación Spring MVC?
- 13. ¿Cómo manejar las excepciones lanzadas al renderizar una vista en Spring MVC?
- 14. ¿Cómo manejar StackOverflowError en Java?
- 15. cómo manejar 'indefinido' en javascript
- 16. Cómo manejar JSON en Dart
- 17. ¿Cómo manejar i18n en Go?
- 18. Wicket: cómo manejar tareas largas
- 19. Cómo manejar ERROR_RECOGNIZER_BUSY
- 20. Cómo manejar un SIGTERM
- 21. Cómo manejar múltiples delegados
- 22. cómo manejar esta ruta?
- 23. Cómo manejar AccessViolationException
- 24. Cómo manejar excepciones DOP
- 25. Cómo manejar MaxUploadSizeExceededException
- 26. Cómo manejar la ActivityNotFoundException?
- 27. ¿Cómo manejar adecuadamente ThreadInterruptedException?
- 28. cómo manejar httpStatuscode correctamente
- 29. ¿Qué alternativas existen para Spring Batch para manejar trabajos en cola?
- 30. Manejar el mensaje de error no autorizado para la autenticación básica en Spring Security
¿Ha tenido una configuración diferente para conseguir que la restricción de usar? Mi restricción es algo como esto 'UK_6DOTKOTT2KJSP8VW4D0M25FB7_INDEX_4' – LTroya
Hay varias formas de crear restricciones legibles: 1. En el script SQL inicial. 2. Generación automática de DB con el parámetro 'uniqueConstraints' en la anotación' @ Table', p. '@Table (name =" meals ", uniqueConstraints = {@UniqueConstraint (columnNames = {" user_id "," date_time "}, name =" meals_unique_user_datetime_idx ")})' – GKislin