如何使用H2数据库获取DataIntegrityViolationException上的constraintName?

时间:2018-10-02 16:21:40

标签: java hibernate h2

我在生产中使用PostgreSQL,在开发中使用H2。

我在SpringBoot ControllerAdvice中处理DataIntegrityViolationException,我想获取驱动此异常的约束的名称。

我的表是这样定义的:

@Table(name = "user", uniqueConstraints = {
    @UniqueConstraint(name = "users_unique_email_idx", columnNames = {"email"})
})
class User ...

当我使用PostgreSQL时,它运行良好。我得到了ConstraintViolationException的异常原因,然后获得了约束名称。像这样的东西:

((ConstraintViolationException)ex.getCause()).getConstraintName()

但是使用H2数据库时,我找不到获取ConstraintName的方法。 DataIntegrityViolationException不包含ConstraintViolationException或constraintName。对于H2,错误消息为空:

DataIntegrityViolationException:
  could not execute statement; SQL [n/a]; constraint [null];
Caused by:
  JdbcSQLException: Violation dindex unique ou clé primaire: {0}
  Unique index or primary key violation: {0}; SQL statement:

注意:在我的H2 INFORMATION_SCHEMA.CONSTRAINTS表中,我对电子邮件字段的约束存在并且具有好名(users_unique_email_idx

是H2数据库的限制吗?
如何在H2中启用约束名称?

谢谢!

1 个答案:

答案 0 :(得分:1)

答案是 Hibernate根据数据库消息转换PostgreSQL约束异常。
在类12000中,我们可以找到一个对象org.hibernate.dialect.PostgreSQL81Dialect,该对象检查数据库中的消息是否包含字符串TemplatedViolatedConstraintNameExtracter。 如果您更改了数据库的语言,则hibernate无法翻译异常,因为它是基于英语的。这就是Hibernate找不到约束名称的原因。 有两种解决方案:

  1. 将环境变量 LC_MESSAGES 更改为英语。来自PostgreSQL的消息将以英语显示。
  2. 扩展PostgreSQL方言类(很少类取决于PostgreSQL版本)并覆盖violates unique constraint。创建自己的getViolatedConstraintNameExtracter对象,然后翻译您的语言。

根据上述内容在H2数据库案例检查中。