Repository navigation
Cannot invoke "java.util.Map.get(Object)" because "apijson.orm.AbstractVerifier.ACCESS_FAKE_DELETE_MAP" is null #654
Description
Activity
没有及时初始化导致的 bug,这里应该在 static 代码块加上
ACCESS_FAKE_DELETE_MAP = new LinkedHashMap<>();
https://github.com/Tencent/APIJSON/blob/master/APIJSONORM/src/main/java/apijson/orm/AbstractVerifier.java#L133-L150

MultiDataSource 等 Demo 没复现是因为 APIJSONVerifier.initAccess 把它初始化了

,但如果没有依赖 apijson-framework 并成功调用 APIJSONVerifier.initAccess,ACCESS_FAKE_DELETE_MAP 照样也没初始化,后面 ACCESS_FAKE_DELETE_MAP.get 也会照样报错 NPE。jitpack 6.3.0 APIJSON 的jar 包 源码也是不对的,
#652 (comment) 这里我有说明
@Override protected String getKey(SQLConfig<String> config, ResultSet rs, ResultSetMetaData rsmd, int tablePosition, JSONObject table, int columnIndex, Map<String, JSONObject> childMap) throws Exception { String key = super.getKey(config, rs, rsmd, tablePosition, table, columnIndex, childMap); // 前端传参驼峰命名转为蛇形命名 return JSONResponse.formatUnderline(key, true); }放开这段代码 后 错误日志
java.lang.IllegalArgumentException: URL 路径 /get/sysUserPage 对应的接口不存在!
at apijson.router.APIJSONRouterController.router(APIJSONRouterController.java:181)
at apijson.router.APIJSONRouterController.router(APIJSONRouterController.java:65)请求参数
{
"SysUser[]":{
"SysUser":{"realName":"超级管理员"},
"page":0,
"count":10
},
"total@":"/SysUser[]/total",
"format":true
}这个问题应该和之前的 ACCESS_FAKE_DELETE_MAP = null 无关,应该是用了 apijson-router 但没配置 Document 记录导致
https://github.com/APIJSON/apijson-router?tab=readme-ov-file#usageHi @TommyLemon, I re-checked #654 against current master (
APIJSONORM8.3.0,c204638b). It still reproduces in a database-free harness that calls the realAbstractSQLConfig.newSQLConfig(...)path with fake delete enabled:- with
ACCESS_FAKE_DELETE_MAP == null, GET fails atAbstractSQLConfig.javaL6046-L6047 and DELETE at L6197-L6198, with the reported NPE; - with a configured
Userentry (deletedKey=is_del,deletedValue=1), DELETE is rewritten to PUT withcontent={is_del=1}.
The map is still declared
@NotNullwithout initialization (AbstractVerifier.javaL114-L115). Eager initialization (new LinkedHashMap<>()in the static block) therefore looks like a narrow fix for the null-static-map path.One boundary needs maintainer guidance: after eager initialization, DELETE with an empty map or no entry for the table still gets
nullat L6198 and dereferences it at L6200. Simply skipping that branch would leave the method as DELETE, so I do not want to assume a physical-delete fallback. Would you prefer this PR to stay limited to eager initialization plus database-free regression tests, leaving missing-entry policy separate, or should it also fail explicitly when fake delete is enabled but the table has no configuration (or use another behavior you prefer)?I also checked #602/#603; they cover adjacent fake-delete behavior but do not apply this initialization. I have not started a patch so we can align first. If this limited scope is useful, may I take #654 and prepare the PR?
- with
Hi @TommyLemon, I re-checked #654 against current master (
APIJSONORM8.3.0,c204638b). It still reproduces in a database-free harness that calls the realAbstractSQLConfig.newSQLConfig(...)path with fake delete enabled:- with
ACCESS_FAKE_DELETE_MAP == null, GET fails atAbstractSQLConfig.javaL6046-L6047 and DELETE at L6197-L6198, with the reported NPE; - with a configured
Userentry (deletedKey=is_del,deletedValue=1), DELETE is rewritten to PUT withcontent={is_del=1}.
The map is still declared
@NotNullwithout initialization (AbstractVerifier.javaL114-L115). Eager initialization (new LinkedHashMap<>()in the static block) therefore looks like a narrow fix for the null-static-map path.One boundary needs maintainer guidance: after eager initialization, DELETE with an empty map or no entry for the table still gets
nullat L6198 and dereferences it at L6200. Simply skipping that branch would leave the method as DELETE, so I do not want to assume a physical-delete fallback. Would you prefer this PR to stay limited to eager initialization plus database-free regression tests, leaving missing-entry policy separate, or should it also fail explicitly when fake delete is enabled but the table has no configuration (or use another behavior you prefer)?I also checked #602/#603; they cover adjacent fake-delete behavior but do not apply this initialization. I have not started a patch so we can align first. If this limited scope is useful, may I take #654 and prepare the PR?
@henriquejsza Thank you for your feedback and sugguestion. The NPE bug should be fixed. ACCESS_FAKE_DELETE_MAP should be eager initialized while it hasn't yet.
https://github.com/Tencent/APIJSON/blob/c204638b5dfe62747f2f373ba8b59259c4ea9cf8/APIJSONORM/src/main/java/apijson/orm/AbstractVerifier.java#L114-L115

When the fake-delete was configured and an error was occurred, it should fail with an Exception, not fallback to real deleting, so that the behavior can be predicted and the error can be warned and noticed, since I think the reason why most developers configure fake-delete is that they don't want the real deleting for certain tables.
Looking forward to your PR~- with
- added a commit that references this issue
on Aug 30, 2026
APIJSON Version/APIJSON 版本号
6.3.0
Database Type & Version/数据库类型及版本号
mysql8
Environment/环境信息
APIAuto Screenshots/APIAuto 请求与结果完整截屏
程序无法启动
Current Behavior/问题描述
Expected Behavior/期望结果
Any additional comments?/其它补充说明?