【问题标题】:org.springframework.dao.DataIntegrityViolationException misreporting cause?org.springframework.dao.DataIntegrityViolationException 误报原因?
【发布时间】:2012-10-25 16:45:12
【问题描述】:

我正在使用 hibernate 插入到所有列都定义为非空的 mysql 表中。它有一个唯一的主键和几个列上的另一个唯一索引。

我收到以下错误:

org.springframework.dao.DataIntegrityViolationException: 不能 执行JDBC批量更新; SQL [插入 MY_TABLE(col1, col2, col3, col4, ID_) 值 (?, ?, ?, ?, ?)];约束 [null]

此错误在客户日志中,我自己无法重现该问题,因此无法进行调试以查看插入语句中的值。

我的理解是,“约束 [null]”意味着违反了“非空”约束。但是,查看我的代码,我看不到任何数据在插入时可能为空的任何可能方式,除非休眠尝试插入空 ID(这将是休眠中的一个非常糟糕的错误,所以看起来不太可能)。

但是,我可以看到违反唯一约束是如何发生的。该消息是否可能具有误导性,并且我实际上遇到了唯一的密钥违规? "constraint[null]" 是否总是意味着违反了非空约束?

【问题讨论】:

  • 除非not null 列尝试提供null 值,否则我无法猜测为什么会导致该异常。顺便说一句,如果您使用的是旧版本的 JDBC 驱动程序,请不要忘记将其替换为最新版本(10+)。否则以后还会引起其他问题。
  • 这是 mysql 5.1,不是 Oracle。

标签: java spring hibernate


【解决方案1】:

如果你在Spring源码中搜索DataIntegrityViolationException的构造函数的调用者,你会发现它在org.springframework.orm.hibernate3.SessionFactoryUtils中被调用:

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

所以异常是由违反约束引起的,null 是 JDBC 异常返回的约束名称。所以你应该责怪 MySQL 驱动程序没有在 JDBC 异常中填充违反的约束名称。但违反的约束可以是任何约束,不一定是not null 约束。

【讨论】:

  • 我明白了,这很烦人,mysql 没有给出名称,但知道非常有帮助!我只是假设 null 表示非 null 约束。谢谢。
【解决方案2】:

您可以直接从 Hibernate 的异常类型中获取 Constain 名称。 使用

getConstraintName

获取数据库约束名称的属性。

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

我使用 contains 是因为我希望这个应用程序在多个数据库架构上运行。默认情况下 getConstraintName 带有数据库名称,如

MyDBName.ConstrainName

【讨论】:

  • ConstraintViolationException 中没有 getConstraintName() 方法
猜你喜欢
  • 1970-01-01
  • 2017-05-22
  • 2016-02-26
  • 2015-08-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多