java - manytomany - ¿Cómo manejar las violaciones de restricciones únicas de JPA?
jpa java ejemplo (7)
¿Cómo puedo descubrir que se violó una restricción única?
Las excepciones están encadenadas, debe llamar a getCause()
recursiva para obtener la excepción específica del proveedor (y tal vez ir a la SQLException
) para traducirla en algo que su aplicación pueda manejar bien para su usuario. Lo siguiente imprimirá la cadena de excepción:
for (t = e.getCause(); t != null; t = t.getCause()) {
logger.debug("Exception:" + t);
}
Para el manejo de excepciones y la "traducción", podría hacer algo como lo que hace Spring (consulte las distintas clases de JpaDialect
, por ejemplo, HibernateJpaDialect
para obtener una idea).
Todo esto no es bueno, este código no será portátil y no será fácil encontrar qué atributo (s) causó la violación. Esto confirma de alguna manera que no hay una manera elegante y portátil de manejar las violaciones de restricciones en JPA .
Cuando se viola una restricción única, se lanza una javax.persistence.RollbackException
. Pero podría haber varias razones para lanzar una RollbackException
. ¿Cómo puedo descubrir que se violó una restricción única?
try {
repository.save(article);
}
catch(javax.persistence.RollbackException e) {
// how to find out the reason for the rollback exception?
}
Creo que imprimir el seguimiento de la pila te ayudará a saber esto. e.printStackTrace ();
Esto puede ser muy tarde para ti, pero aquí es cómo lo resolví para PostGres.
catch (DataIntegrityViolationException e) {
for (Throwable t = e.getCause(); t != null; t = t.getCause()) {
if (PSQLException.class.equals(t.getClass())) {
PSQLException postgresException = (PSQLException) t;
// In Postgres SQLState 23505=unique_violation
if ("23505".equals(postgresException.getSQLState())) {
throw new CustomDataAlreadyExistsException("YourErrorCode", e);
}
}
}
throw new SomeOtherException("YourErrorCode2", e);
}
Puedes hacer así:
StringWriter writer=new StringWriter(); //remains the message from stack trace.
e.printStackTrace(new PrintWriter(writer));
String message=writer.toString(); // gets the message of full stack trace.
Y luego ver la información de excepción.
Puedes usar lo siguiente:
Si está utilizando Spring Framework, entonces puede usar:
org.springframework.dao.DataIntegrityViolationException
Si se puede utilizar el siguiente estándar JPA
org.hibernate.exception.ConstraintViolationException
A nivel de sql se puede usar lo siguiente:
java.sql.SQLIntegrityConstraintViolationException
Use e.getCause()
para examinar qué causó la reversión.
el compilador devuelve la excepción SQLIntegrityConstraintViolationException , mientras trata de violar una restricción única.
Use el siguiente concepto de bloque de captura para manejar las excepciones apropiadas.
catch(SQLIntegrityConstraintViolationException e)
{
// Error message for integrity constraint violation
}
catch(Exception e)
{
// Other error messages
}