JOOQ 3.9.6中RecordListener无法捕获updateStart与updateEnd事件
解决JOOQ 3.9.6中RecordListener的updateEnd不触发问题
我之前也踩过这个坑,先给你捋清楚核心逻辑——JOOQ的RecordListener只监听基于Record实例的CRUD操作,而你现在用的DSLContext.update(...).execute()属于直接执行SQL的「DSL式操作」,完全绕开了Record实例的生命周期,所以updateEnd自然不会被触发。至于insertEnd能正常工作,大概率是你插入时用了Record.insert()或Record.store()这类Record实例的方法对吧?
两种可行解决方案
方案1:改用Record实例的update方法(继续用RecordListener)
如果想保留AuditListener的updateEnd逻辑,得先把要更新的记录查询出来,修改后调用Record的update()方法,这样就能触发监听了:
// 先获取目标Record UserRecord userRecord = dslContext.fetchOne(USER_TABLE, USER_TABLE.ID.eq(1)); // 修改字段值 userRecord.setUserName("UpdatedNickname"); // 调用Record的update方法,这会触发updateEnd回调 userRecord.update();
方案2:改用ExecuteListener监听所有SQL更新
如果你的业务需要监听所有update操作(包括DSL式的批量更新),那应该换成ExecuteListener,它能覆盖所有SQL执行的生命周期:
public class AuditExecuteListener extends DefaultExecuteListener { @Override public void executeEnd(ExecuteContext ctx) { // 判断当前执行的是update语句 if (ctx.query() instanceof UpdateQuery) { // 这里写你原来在updateEnd里的审计逻辑 System.out.println("Update操作执行完成,开始审计"); } } }
记得把这个Listener注册到JOOQ配置里:
Configuration config = new DefaultConfiguration() .set(SQLDialect.YOUR_DIALECT) // 替换成你用的数据库方言,比如SQLDialect.MYSQL .set(yourDataSource) .set(new AuditListener()) // 保留原RecordListener处理Record操作 .set(new AuditExecuteListener()); // 添加ExecuteListener处理DSL操作 DSLContext dslContext = DSL.using(config);
额外说明
JOOQ 3.9.6的官方文档也明确标注了:RecordListener的回调方法仅针对UpdatableRecord、InsertableRecord等实例的update()、insert()、delete()方法触发;而DSL的update()、insert()是直接生成并执行SQL,不会走Record的监听链路。
内容的提问来源于stack exchange,提问作者Nico
相关产品推荐
相关产品推荐

