Tencent/APIJSON · critical · NullPointerException
服务器内部错误,List<Join> 中 Join.onList[0].getKey() = null!
Error message
服务器内部错误,List<Join> 中 Join.onList[0].getKey() = null!
What it means
Internal NullPointerException from executeAppJoin: the first On has an originKey but getKey() returns null. The key names the main-table column to pull target values from (e.g. userId in "userId@/User/id"); a null key makes the subsequent mainTable.get(on.getTargetKey()) / mapping logic impossible, so execution aborts.
Source
Thrown at APIJSONORM/src/main/java/apijson/orm/AbstractSQLExecutor.java:786
SQLConfig<T, M, L> cc = join.getCacheConfig(); //这里用config改了getSQL后再还原很麻烦,所以提前给一个config2更好
if (cc == null) {
if (Log.DEBUG) {
throw new NullPointerException("服务器内部错误, executeAppJoin cc == null ! 导致不能缓存 @ APP JOIN 的副表数据!");
}
continue;
}
SQLConfig<T, M, L> jc = join.getJoinConfig();
List<On> onList = join.getOnList();
On on = onList == null || onList.isEmpty() ? null : onList.get(0); // APP JOIN 应该有且只有一个 ON 条件
String originKey = on == null ? null : on.getOriginKey();
if (originKey == null) {
throw new NullPointerException("服务器内部错误,List<Join> 中 Join.onList[0" + (on == null ? "] = null!" : ".getOriginKey() = null!"));
}
String key = on.getKey();
if (key == null) {
throw new NullPointerException("服务器内部错误,List<Join> 中 Join.onList[0" + (on == null ? "] = null!" : ".getKey() = null!"));
}
// 取出 "id@": "@/User/userId" 中所有 userId 的值
List<Object> targetValueList = new ArrayList<>();
for (int i = 0; i < resultList.size(); i++) {
M mainTable = resultList.get(i);
Object targetValue = mainTable == null ? null : mainTable.get(on.getTargetKey());
if (targetValue != null && targetValueList.contains(targetValue) == false) {
targetValueList.add(targetValue);
}
}
if (targetValueList.isEmpty() && config.isExplain() == false) {
throw new NotExistException("targetValueList.isEmpty() && config.isExplain() == false");
}
View on GitHub (pinned to 5284052872)
Solutions
- Provide the full relation including the local column: "MyTable/userId@/User/id".
- When constructing On in code, always setKey with the local column name.
- Validate joiner strings with a regex like [A-Za-z0-9_$]+/[^/@]+@/[^/@]+/[^/@]+ before use.
Example fix
// before
"join": {"/User/id": "@ APP"}
// after
"join": {"Comment/userId@/User/id": "@ APP"} Defensive patterns
Strategy: try-catch
Validate before calling
if (on != null && on.getKey() == null) throw new IllegalStateException('APP JOIN On missing local key'); Try / catch
catch (NullPointerException npe) { if (String(npe.getMessage()).contains("Join.onList[0].getKey() = null")) { throw new BadRequestException('join key must include local column before @'); } } Prevention
- Include the local column name before '@' in every join relation.
- Reject join keys starting with '/' client-side.
When it happens
Trigger: On objects built without setKey, or a joiner string whose key portion before '@' is empty ("/User/id" as the relation segment).
Common situations: Programmatic On construction; malformed joiner strings missing the leading column name; extension code copying On objects field-by-field and skipping key.
Related errors
- 服务器内部错误,List<Join> 中 Join.onList[0] = null!
- 服务器内部错误,List<Join> 中 Join.onList[0].getOriginKey() = null!
- 服务器内部错误,List<Join> 中 Join.onList[{}] = null!
- 服务器内部错误,List<Join> 中 Join.onList[{}].getOriginKey() = null!
- AbstractSQLExecutor.executeAppJoin StringUtil.isEmpty(sql,
AI-assisted analysis of Tencent/APIJSON@5284052872 (2026-08-14).
Data as JSON: /api/errors/d5041a22cf7b3263.
Report an issue: GitHub.