jeremieca
jeremieca

Reputation: 1188

How to get constraintName on DataIntegrityViolationException using H2 database?

I'm using PostgreSQL on production and H2 on development.

I handle DataIntegrityViolationException in a SpringBoot ControllerAdvice and I want to get the name of the constraint that drives to this exception.

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. I get the cause of exception which is a ConstraintViolationException and then get the constraint name. Something like that :

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

But using H2 Database I can't find a way to get the constraintName. The DataIntegrityViolationException doesn't contain the ConstraintViolationException or the constraintName. With H2 the error message is empty :

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)

Is it a limitation of H2 Database ?
How can I enable constraint name in H2 ?

Thanks !

Upvotes: 0

Views: 1836

Answers (1)

Michał Budziło
Michał Budziło

Reputation: 26

Answer is Hibernate translate PostgreSQL contraints exception base on database messages.
In class org.hibernate.dialect.PostgreSQL81Dialect we can find a objectTemplatedViolatedConstraintNameExtracter that checks if the message from database contains string violates unique constraint. if you changed the language for database, hibernate cannot translate the exception because it is based on English. This is the reason why Hibernate cannot find the constraint name. There are 2 solutions:

  1. Change environment variables LC_MESSAGES to English. messages from PostgreSQL will be presented in English.
  2. Extend PostgreSQL dialect class (there are few classes depends on PostgreSQL version) and override getViolatedConstraintNameExtracter. Create your own ViolatedConstraintNameExtracter object than will translate your language.

In H2 Database case check according to above.

Upvotes: 1

Related Questions