You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JDBI SQL模板if条件报错:Undefined attribute for token '<endif>'排查

问题:JDBI SQL模板if条件导致Undefined attribute for token '<endif>'异常

使用JDBI框架时触发org.jdbi.v3.core.statement.UnableToCreateStatementException异常,提示信息为Undefined attribute for token ''。

Dao接口方法

@RegisterRowMapper(MapMapper.class)
@SqlQuery(
    "SELECT Table1.tenantId,Table1.sacTenantId, sacLogId,currentStep,status  from Table1 inner join Table2 on Table1.tenantId = Table2.tenantId where <if(tenantId)>Table1.tenantId = :tenantId and<endif> Table2.status = 'FAILED'"
)
List<Map<String, Object>> getTenantFailedJobDetails(@Define("tenantId") @Bind("tenantId") String tenantId);

错误追踪信息

"level":"ERROR","categories":[],"msg":"Servlet.service() for servlet
[dispatcherServlet] in context with path [] threw exception [Request
processing failed; nested exception is
org.jdbi.v3.core.statement.UnableToCreateStatementException: Error
rendering SQL template: 'SELECT Table1.tenantId,Table1.sacTenantId,
sacLogId,currentStep,status from Table1 inner join Table2 on
Table1.tenantId = Table2.tenantId where <if(tenantId)>Table1.tenantId
= :tenantId and Table2.status = 'FAILED'' [statement:"null", arguments:{positional:{0:DUMMY-TENANT}, named:{tenantId:DUMMY-TENANT},
finder:[]}]] with root
cause","stacktrace":["org.jdbi.v3.core.statement.UnableToCreateStatementException:
Undefined attribute for token '' [statement:"null",
arguments:{positional:{0:DUMMY-TENANT}, named:{tenantId:DUMMY-TENANT},
finder:[]}]"


问题原因与修复方案

核心问题

你混淆了JDBI与其他ORM框架(如MyBatis)的模板语法:JDBI的SQL模板中,<if>标签的闭合标记是</if>,而非<endif>。<endif>是MyBatis的专属语法,JDBI无法识别该标记,因此抛出“未定义属性”的异常。

修复后的代码

将<endif>替换为</if>即可解决异常:

@RegisterRowMapper(MapMapper.class)
@SqlQuery(
    "SELECT Table1.tenantId,Table1.sacTenantId, sacLogId,currentStep,status  from Table1 inner join Table2 on Table1.tenantId = Table2.tenantId where <if(tenantId)>Table1.tenantId = :tenantId and</if> Table2.status = 'FAILED'"
)
List<Map<String, Object>> getTenantFailedJobDetails(@Define("tenantId") @Bind("tenantId") String tenantId);

额外优化建议

当前SQL逻辑在tenantId为空时会正常渲染为where Table2.status = 'FAILED',但如果后续调整条件顺序,可能出现多余的and。可以将固定条件前置,或者使用<if>包裹整个可变条件块并包含and,避免语法隐患:

@SqlQuery(
    "SELECT Table1.tenantId,Table1.sacTenantId, sacLogId,currentStep,status  from Table1 inner join Table2 on Table1.tenantId = Table2.tenantId where Table2.status = 'FAILED' <if(tenantId)>and Table1.tenantId = :tenantId</if>"
)

内容的提问来源于stack exchange,提问作者Saqib Hussain

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 02:39:09