来自触发器的异常映射 - spring-boot 2.4.x + jOOQ
Unexpected mapping of exception from trigger - spring-boot 2.4.x + jOOQ
我们正在使用 spring-boot 和 spring-boot-starter-jooq。对于一些复杂的约束检查,使用触发器会引发特定消息的错误。异常被持久层捕获并转化为业务异常
上次 spring 引导版本 2.4.x 中的行为已更改。例如带有 scherma 的 hsqldb:
CREATE TABLE tab1 (
K INT PRIMARY KEY
)^;
CREATE TRIGGER trig1 BEFORE INSERT ON tab1
BEGIN ATOMIC
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'some error';
END^;
和插入 table 的代码:
@Transactional
public void withTriggerException() {
create.insertInto(DSL.table("tab1"))
.set(DSL.field("k"), 1)
.execute();
}
抛出异常的类型和消息与spring-boot版本不同。
2.3.6, 2.3.9
org.springframework.jdbc.UncategorizedSQLException
:jOOQ;未分类 SQL SQL 异常 [插入 tab1 (k) 值 (cast(? as int))]; SQL状态[45000];错误代码 [5800];一些错误;嵌套异常是 java.sql.SQLException: 一些错误
2.4.0、2.4.1、2.4.2
java.lang.NullPointerException
: 空
2.4.3
org.jooq.exception.DataAccessException
: SQL [insert into tab1 (k) values (?)];未指定的 RuntimeException
at org.jooq_3.14.7.HSQLDB.debug(Unknown Source) ~[na:na]
at org.jooq.impl.Tools.translate(Tools.java:2892) ~[jooq-3.14.7.jar:na]
at org.jooq.impl.DefaultExecuteContext.exception(DefaultExecuteContext.java:730) ~[jooq-3.14.7.jar:na]
at org.springframework.boot.autoconfigure.jooq.JooqExceptionTranslator.handle(JooqExceptionTranslator.java:83) ~[spring-boot-autoconfigure-2.4.3.jar:2.4.3]
at org.springframework.boot.autoconfigure.jooq.JooqExceptionTranslator.exception(JooqExceptionTranslator.java:55) ~[spring-boot-autoconfigure-2.4.3.jar:2.4.3]
at org.jooq.impl.ExecuteListeners.exception(ExecuteListeners.java:274) ~[jooq-3.14.7.jar:na]
at org.jooq.impl.AbstractQuery.execute(AbstractQuery.java:390) ~[jooq-3.14.7.jar:na]
at org.jooq.impl.AbstractDelegatingQuery.execute(AbstractDelegatingQuery.java:119) ~[jooq-3.14.7.jar:na]
at com.example.demo.FooDAO.withTriggerException(DemoApplication.java:38) ~[classes/:na]
...
该行为已在 hsqldb 上重现,但在 PostgreSQL 上相同。另一个错误(重复键、外键等)正在按预期工作。
可以通过 spring-boot 2.4.x?
从触发器中获取错误消息(示例中的“某些错误”)
您可能 运行 遇到这个问题:
- https://github.com/jOOQ/jOOQ/issues/11304,已在 jOOQ 3.14.6 和 3.15.0 中修复。
关于 Spring 中的不兼容变化的一些背景,在 jOOQ 中产生了这种 NPE 回归,可以在这里看到:
修复应该在 Spring Boot 2.5.0 和 2.4.3 中可用:
- https://github.com/spring-projects/spring-boot/issues/25214
- https://github.com/spring-projects/spring-boot/issues/25240
您应该能够使用 DataAccessException.getCause(Class)
从 jOOQ 的 DataAccessException
访问 JDBC SQLException
,例如
exception.getCause(SQLException.class);
但可能有更好的方法让 Spring 异常 t运行slator 直接为您提供实际原因。
我们正在使用 spring-boot 和 spring-boot-starter-jooq。对于一些复杂的约束检查,使用触发器会引发特定消息的错误。异常被持久层捕获并转化为业务异常
上次 spring 引导版本 2.4.x 中的行为已更改。例如带有 scherma 的 hsqldb:
CREATE TABLE tab1 (
K INT PRIMARY KEY
)^;
CREATE TRIGGER trig1 BEFORE INSERT ON tab1
BEGIN ATOMIC
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'some error';
END^;
和插入 table 的代码:
@Transactional
public void withTriggerException() {
create.insertInto(DSL.table("tab1"))
.set(DSL.field("k"), 1)
.execute();
}
抛出异常的类型和消息与spring-boot版本不同。
2.3.6, 2.3.9
org.springframework.jdbc.UncategorizedSQLException
:jOOQ;未分类 SQL SQL 异常 [插入 tab1 (k) 值 (cast(? as int))]; SQL状态[45000];错误代码 [5800];一些错误;嵌套异常是 java.sql.SQLException: 一些错误
2.4.0、2.4.1、2.4.2
java.lang.NullPointerException
: 空
2.4.3
org.jooq.exception.DataAccessException
: SQL [insert into tab1 (k) values (?)];未指定的 RuntimeException
at org.jooq_3.14.7.HSQLDB.debug(Unknown Source) ~[na:na]
at org.jooq.impl.Tools.translate(Tools.java:2892) ~[jooq-3.14.7.jar:na]
at org.jooq.impl.DefaultExecuteContext.exception(DefaultExecuteContext.java:730) ~[jooq-3.14.7.jar:na]
at org.springframework.boot.autoconfigure.jooq.JooqExceptionTranslator.handle(JooqExceptionTranslator.java:83) ~[spring-boot-autoconfigure-2.4.3.jar:2.4.3]
at org.springframework.boot.autoconfigure.jooq.JooqExceptionTranslator.exception(JooqExceptionTranslator.java:55) ~[spring-boot-autoconfigure-2.4.3.jar:2.4.3]
at org.jooq.impl.ExecuteListeners.exception(ExecuteListeners.java:274) ~[jooq-3.14.7.jar:na]
at org.jooq.impl.AbstractQuery.execute(AbstractQuery.java:390) ~[jooq-3.14.7.jar:na]
at org.jooq.impl.AbstractDelegatingQuery.execute(AbstractDelegatingQuery.java:119) ~[jooq-3.14.7.jar:na]
at com.example.demo.FooDAO.withTriggerException(DemoApplication.java:38) ~[classes/:na]
...
该行为已在 hsqldb 上重现,但在 PostgreSQL 上相同。另一个错误(重复键、外键等)正在按预期工作。
可以通过 spring-boot 2.4.x?
从触发器中获取错误消息(示例中的“某些错误”)您可能 运行 遇到这个问题:
- https://github.com/jOOQ/jOOQ/issues/11304,已在 jOOQ 3.14.6 和 3.15.0 中修复。
关于 Spring 中的不兼容变化的一些背景,在 jOOQ 中产生了这种 NPE 回归,可以在这里看到:
修复应该在 Spring Boot 2.5.0 和 2.4.3 中可用:
- https://github.com/spring-projects/spring-boot/issues/25214
- https://github.com/spring-projects/spring-boot/issues/25240
您应该能够使用 DataAccessException.getCause(Class)
从 jOOQ 的 DataAccessException
访问 JDBC SQLException
,例如
exception.getCause(SQLException.class);
但可能有更好的方法让 Spring 异常 t运行slator 直接为您提供实际原因。