web-dev-qa-db-fra.com

Comment gérer les violations de contraintes uniques JPA?

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?
}
19
deamon

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 .

17
Pascal Thivent

Utilisez e.getCause() pour examiner la cause de la restauration.

3
Aaron Digulla

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
}
1
abhijitcaps

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

1
AaMng

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);

        }
1
AjayPS

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.

0
Mercy

je pense qu'imprimer la trace de la pile vous aidera à le savoir. e.printStackTrace ();

0
hakish