简体   繁体   English

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

[英]How to get constraintName on DataIntegrityViolationException using H2 database?

I'm using PostgreSQL on production and H2 on development.我在生产中使用 PostgreSQL,在开发中使用 H2。

I handle DataIntegrityViolationException in a SpringBoot ControllerAdvice and I want to get the name of the constraint that drives to this exception.我在 SpringBoot ControllerAdvice 中处理DataIntegrityViolationException并且我想获取导致此异常的约束的名称。

My table is defined like that :我的表是这样定义的:

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

When I use PostgreSQL it works perfectly.当我使用 PostgreSQL 时,它运行良好。 I get the cause of exception which is a ConstraintViolationException and then get the constraint name.我得到异常的原因,这是一个ConstraintViolationException ,然后得到约束名称。 Something like that :类似的东西:

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

But using H2 Database I can't find a way to get the constraintName.但是使用 H2 数据库我找不到获取constraintName 的方法。 The DataIntegrityViolationException doesn't contain the ConstraintViolationException or the constraintName. DataIntegrityViolationException不包含ConstraintViolationException或约束名称。 With H2 the error message is empty :对于 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:

Note : In my H2 INFORMATION_SCHEMA.CONSTRAINTS table my constraint on email field exists and has the good name ( users_unique_email_idx )注意:在我的 H2 INFORMATION_SCHEMA.CONSTRAINTS表中,我对电子邮件字段的约束存在并且具有良好的名称( users_unique_email_idx

Is it a limitation of H2 Database ?它是 H2 数据库的限制吗?
How can I enable constraint name in H2 ?如何在 H2 中启用约束名称?

Thanks !谢谢 !

Answer is Hibernate translate PostgreSQL contraints exception base on database messages.答案是 Hibernate 根据数据库消息翻译 PostgreSQL 约束异常。
In class org.hibernate.dialect.PostgreSQL81Dialect we can find a object TemplatedViolatedConstraintNameExtracter that checks if the message from database contains string violates unique constraint .org.hibernate.dialect.PostgreSQL81Dialect类中,我们可以找到一个对象TemplatedViolatedConstraintNameExtracter来检查来自数据库的消息是否包含violates unique constraint字符串。 if you changed the language for database, hibernate cannot translate the exception because it is based on English.如果您更改了数据库的语言,hibernate 无法翻译异常,因为它是基于英语的。 This is the reason why Hibernate cannot find the constraint name.这就是 Hibernate 找不到约束名称的原因。 There are 2 solutions:有2种解决方案:

  1. Change environment variables LC_MESSAGES to English.将环境变量LC_MESSAGES更改为英语。 messages from PostgreSQL will be presented in English.来自 PostgreSQL 的消息将以英文显示。
  2. Extend PostgreSQL dialect class (there are few classes depends on PostgreSQL version) and override getViolatedConstraintNameExtracter .扩展 PostgreSQL 方言类(有几个类取决于 PostgreSQL 版本)并覆盖getViolatedConstraintNameExtracter Create your own ViolatedConstraintNameExtracter object than will translate your language.创建您自己的ViolatedConstraintNameExtracter对象,然后翻译您的语言。

In H2 Database case check according to above.在 H2 数据库中,根据上述情况进行检查。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM