1. ホーム
  2. java

[解決済み] org.springframework.dao.DataIntegrityViolationException の誤報の原因?

2022-03-12 13:45:43

質問

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

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

org.springframework.dao.DataIntegrityViolationException: Could not JDBC バッチアップデートの実行; SQL [insert into MY_TABLE(col1, col2, col3, col4, ID_) values (?, ?, ?, ?, ?)]; constraint [null].

このエラーは顧客ログにあり、自分では再現できないので、insert文の値がどうなっているのかデバッグを入れることができません。

私の理解では、"制約 [null]" は、"not null" 制約に違反していることを意味します。しかし、私のコードを見ると、hibernateがNULL IDを挿入しようとしていない限り、挿入時にデータがNULLになる可能性はありません(これはhibernateの非常に悪いバグなので、可能性は低いと思われます)。

しかし、一意性制約に違反していることが起こる可能性があることはわかります。このメッセージは誤解を招くもので、実際にはユニークキー違反が発生している可能性はありませんか?constraint[null]"は常にnullでない制約に違反したことを意味するのでしょうか?

解決方法を教えてください。

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 制約があります。