Lorsqu'une contrainte unique est violée, un javax.persistence.RollbackException
est renvoyé. Mais il peut y avoir plusieurs raisons de lancer une RollbackException
. Comment puis-je savoir qu'une contrainte unique a été violée?
try {
repository.save(article);
}
catch(javax.persistence.RollbackException e) {
// how to find out the reason for the rollback exception?
}
Comment puis-je savoir qui a été violé une contrainte unique?
Exception sont enchaînés, vous devez appeler getCause()
récursive pour obtenir le fournisseur exception spécifique (et peut-être aller jusqu'à la SQLException
) pour le traduire en quelque chose que votre application peut gérer bien pour l'utilisateur. Ce qui suit imprimera la chaîne d'exception:
for (t = e.getCause(); t != null; t = t.getCause()) {
logger.debug("Exception:" + t);
}
Pour la gestion des exceptions et la « traduction », vous pouvez faire quelque chose comme ce printemps ne (voir les différentes classes JpaDialect
, par exemple HibernateJpaDialect
pour avoir une idée).
Tout cela n'est pas Nice, ce code ne sera pas portable et trouver ce que l'attribut (s) a causé la violation ne sera pas facile. Cela confirme en quelque sorte qu'il n'y a pas de façon élégante et portable pour gérer les violations de contrainte dans JPA .
Utilisez e.getCause()
pour examiner la cause de la restauration.
le compilateur renvoie l'exception SQLIntegrityConstraintViolationException , en essayant de violer une contrainte unique
Utilisez le concept de bloc d'arrêt suivant pour gérer les exceptions appropriées.
catch(SQLIntegrityConstraintViolationException e)
{
// Error message for integrity constraint violation
}
catch(Exception e)
{
// Other error messages
}
Vous pouvez utiliser ce qui suit:
Si vous utilisez le cadre de printemps, vous pouvez utiliser:
org.springframework.dao.DataIntegrityViolationException
Si la norme JPA suivant peut être utilisé
org.hibernate.exception.ConstraintViolationException
Au niveau sql suivant peut être utilisé:
Java.sql.SQLIntegrityConstraintViolationException
Cela pourrait vous arriver très tard, mais voici comment je l’ai résolu pour 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);
}
Vous pouvez faire comme ça:
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.
Et puis voir les informations d'exception.
je pense qu'imprimer la trace de la pile vous aidera à le savoir. e.printStackTrace ();