web-dev-qa-db-ja.com

JPA固有の制約違反を処理する方法は?

一意制約に違反すると、javax.persistence.RollbackExceptionがスローされます。ただし、RollbackExceptionをスローする理由はいくつかあります。一意制約に違反していることをどのように確認できますか?

try {
    repository.save(article);
}
catch(javax.persistence.RollbackException e) {
    // how to find out the reason for the rollback exception?
}
23
deamon

一意制約に違反していることをどのように確認できますか?

例外はチェーン化されています。getCause()を再帰的に呼び出してプロバイダー固有の例外を取得し(そしてSQLExceptionに移動して)、アプリケーションがユーザーにとって適切に処理できるものに変換する必要があります。以下は例外のチェーンを出力します:

for (t = e.getCause(); t != null; t = t.getCause()) {
    logger.debug("Exception:" + t);
}

例外処理と「変換」については、Springが行うようなことを行うことができます(さまざまなJpaDialectクラス、たとえば HibernateJpaDialect を参照してください)。

これはいいことではありません。このコードは移植できず、違反の原因となった属性を見つけるのは簡単ではありません。これにより、JPAの制約違反を処理する のエレガントで移植可能な方法がないことが何らかの形で確認されます

19
Pascal Thivent

e.getCause()を使用して、ロールバックの原因を調べます。

3
Aaron Digulla

コンパイラーは、一意の制約に違反しようとしたときに、例外SQLIntegrityConstraintViolationExceptionを返します。

適切な例外を処理するには、次のキャッチブロックの概念を使用します。

catch(SQLIntegrityConstraintViolationException e) 
{
  // Error message for integrity constraint violation
}
catch(Exception e)
{
 // Other error messages
}
2
abhijitcaps

次のものを使用できます。

Springフレームワークを使用している場合は、次を使用できます:

org.springframework.dao.DataIntegrityViolationException

標準のJPAが使用できる場合

org.hibernate.exception.ConstraintViolationException

SQLレベルでは、以下を使用できます。

Java.sql.SQLIntegrityConstraintViolationException

2
AaMng

これは非常に遅いかもしれませんが、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

あなたはこのようにすることができます:

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.

そして、例外の情報を表示します。

0
Mercy

スタックトレースを印刷すると、これを知るのに役立ちます。 e.printStackTrace();

0
hakish