14

私はhibernateを使用して、すべての列がnullではないと定義されているmysqlテーブルに挿入しています。一意の主キーと、いくつかの列に別の一意のインデックスがあります。

次のエラーが発生します。

org.springframework.dao.DataIntegrityViolationException:JDBCバッチ更新を実行できませんでした。SQL [MY_TABLE(col1、col2、col3、col4、ID_)の値(?、?、?、?、?)に挿入]; 制約[null]

このエラーはカスタマーログにあり、自分で問題を再現することはできないため、デバッグを行って挿入ステートメントの値を確認することはできません。

私の理解では、「制約[null]」は「nullではない」制約に違反していることを意味します。ただし、私のコードを見ると、hibernateがnull IDを挿入しようとしない限り、挿入時にデータがnullになる可能性のある方法を見つけることができません(これはhibernateの非常に悪いバグであるため、ありそうもない)。

ただし、一意の制約に違反している可能性があることがわかります。メッセージが誤解を招き、実際に一意のキー違反が発生している可能性はありますか?「constraint[null]」は常にnull以外の制約に違反したことを意味しますか?

4

2 に答える 2

13

Spring ソース コードで DataIntegrityViolationException のコンストラクターの呼び出し元を検索すると、次の場所で呼び出されていることがわかりますorg.springframework.orm.hibernate3.SessionFactoryUtils

return new DataIntegrityViolationException(ex.getMessage()  + "; SQL [" + jdbcEx.getSQL() +
                "]; constraint [" + jdbcEx.getConstraintName() + "]", ex);

したがって、例外は違反した制約によって引き起こされnull、JDBC 例外によって返される制約の名前です。したがって、違反した制約名を JDBC 例外に入力しなかったことについて、MySQL ドライバーを非難する必要があります。ただし、違反した制約は任意の制約である可能性があり、必ずしも制約であるとは限りませんnot null

于 2012-11-05T20:21:20.193 に答える
2

Constain 名は、Hibernate の例外タイプから直接取得できます。使用する

getConstraintName

DB 制約名を取得するプロパティ。

} catch (ConstraintViolationException conEx) {
            if (conEx.getConstraintName().contains("PROJECT_UK")) {
                //TODO Project Entity is violating it's constrain

このアプリを複数の DB スキーマで実行したいので、contains を使用しました。デフォルトでは、getConstraintName には次のような DB 名が付いています

MyDBName.ConstrainName

于 2013-08-15T11:36:41.277 に答える