2012-11-05 28 views
11

我使用hibernate插入到所有列被定義爲非空的mysql表中。它在幾列上有一個唯一的主鍵和另一個唯一的索引。org.springframework.dao.DataIntegrityViolationException誤報原因?

,我發現了以下錯誤:

org.springframework.dao.DataIntegrityViolationException: Could not execute JDBC batch update; SQL [insert into MY_TABLE(col1, col2, col3, col4, ID_) values (?, ?, ?, ?, ?)]; constraint [null]

此錯誤是在客戶登錄,我無法重現自己的問題,所以我不能把調試,看看有什麼值是插入語句。

我的理解是,「約束[null]」意味着違反了「非空」約束。然而,看看我的代碼,我看不出任何可能的方式,任何數據在插入時都可能爲空,除非hibernate試圖插入空ID(這在hibernate中是一個非常糟糕的錯誤,所以看起來好像不太可能)。

但是,我可以看到它是如何發生的,唯一的約束被違反。信息有可能是誤導性的,我實際上得到了唯一的密鑰違規? 「constraint [null]」是否總是意味着違反了非空約束?

+0

我無法猜測爲什麼,除非'不null'列試圖給一個'null'值異常引起的。順便說一句,如果您使用的是較早版本的JDBC驅動程序,那麼請不要忘記將其替換爲最新版本(10+)。否則,以後會引起其他問題。 – Lion

+0

這是mysql 5.1,不是Oracle。 – Dana

回答

11

如果搜索DataIntegrityViolationException在春源代碼構造函數的調用者,你會發現,這就是所謂的org.springframework.orm.hibernate3.SessionFactoryUtils

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

所以異常是由違反約束引起的,null是由JDBC異常返回的約束的名稱。因此,您應該責怪MySQL驅動程序未在JDBC異常中填充違反的約束名稱。但違反的約束可能是任何約束,而不一定是約束。

+1

我明白了,那非常煩人,mysql並沒有給出這個名字,但知道它非常有幫助!我只是假定null意味着一個非null約束。謝謝。 – Dana

1

您可以直接從Hibernate的異常類型中獲取Constain名稱。 使用

getConstraintName

要獲取數據庫約束名稱的屬性。

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

我已經使用包含,因爲我希望此應用程序運行在多個DB架構上。默認情況下getConstraintName帶有DB名稱就像

MyDBName.ConstrainName

+0

ConstraintViolationException中沒有更多的getConstraintName()方法 – Anna

相關問題