java - 如何使用 H2 数据库在 DataIntegrityViolationException 上获取约束名称?
问题描述
我在生产中使用 PostgreSQL,在开发中使用 H2。
我DataIntegrityViolationException
在 SpringBoot ControllerAdvice 中处理,我想获取驱动此异常的约束的名称。
我的表是这样定义的:
@Table(name = "user", uniqueConstraints = {
@UniqueConstraint(name = "users_unique_email_idx", columnNames = {"email"})
})
class User ...
当我使用 PostgreSQL 时,它可以完美运行。我得到异常的原因是 aConstraintViolationException
然后得到约束名称。类似的东西:
((ConstraintViolationException)ex.getCause()).getConstraintName()
但是使用 H2 数据库我找不到获取约束名称的方法。DataIntegrityViolationException
不包含或ConstraintViolationException
约束名称。使用 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:
注意:在我的 H2INFORMATION_SCHEMA.CONSTRAINTS
表中,我对电子邮件字段的约束存在并且具有良好的名称 ( users_unique_email_idx
)
这是 H2 数据库的限制吗?
如何在 H2 中启用约束名称?
谢谢 !
解决方案
答案是 Hibernate 根据数据库消息翻译 PostgreSQL 约束异常。
在类org.hibernate.dialect.PostgreSQL81Dialect
中,我们可以找到一个对象TemplatedViolatedConstraintNameExtracter
来检查来自数据库的消息是否包含字符串violates unique constraint
。如果您更改了数据库的语言,hibernate 无法翻译异常,因为它是基于英语的。这就是 Hibernate 找不到约束名称的原因。有2个解决方案:
- 将环境变量LC_MESSAGES更改为英文。来自 PostgreSQL 的消息将以英文显示。
- 扩展 PostgreSQL 方言类(有少数类取决于 PostgreSQL 版本)并覆盖
getViolatedConstraintNameExtracter
. 创建您自己的ViolatedConstraintNameExtracter
对象,而不是翻译您的语言。
在 H2 数据库案例中根据上述检查。
推荐阅读
- sql-server - 删除重复的 XML 属性 - SQL Server
- javascript - 重新加载 localStorage 项目更改 javascript 上的所有打开选项卡
- kubernetes - 如何修复 Spinnaker 安装错误“无法部署 Spinnaker”。(大三角帆v2模式安装)?
- javascript - 通过在javascript中传递键和值从数组中获取对象
- svg - 带有 Bootstrap 的 SVG 徽标
- excel - 如何读取与在一系列单元格(excel)中输入的文件名匹配的同一文件夹中的每个文件?并对所有文件执行相同的操作?
- git - 如何防止使用 husky 直接提交到 master 分支?
- php - 忽略标点符号并突出显示给定字符串中的模式
- r - SQL 查询无法识别的唯一标识符
- java - Java Mockito - 在 DocumentBuilder.parse 期间无法抛出 IOException