{"record":{"id":"add28bedc0264501","repo":"jeecgboot/JeecgBoot","slug":"column","errorCode":null,"errorMessage":"请注意，将要排序的列字段不存在：${column}","messagePattern":"请注意，将要排序的列字段不存在：(.+?)","errorType":"validation","errorClass":"JeecgBootException","httpStatus":null,"severity":"error","filePath":"jeecg-boot/jeecg-boot-base-core/src/main/java/org/jeecg/common/system/query/QueryGenerator.java","lineNumber":335,"sourceCode":"\t\t\treturn;\n\t\t}\n\t\t\n\t\t//TODO 避免用户自定义表无默认字段创建时间，导致排序报错\n\t\tif(DataBaseConstant.CREATE_TIME.equals(column) && !fieldColumnMap.containsKey(DataBaseConstant.CREATE_TIME)){\n\t\t\tcolumn = \"id\";\n\t\t\tlog.warn(\"检测到实体里没有字段createTime，改成采用ID排序！\");\n\t\t}\n\t\t\n\t\tif (oConvertUtils.isNotEmpty(column) && oConvertUtils.isNotEmpty(order)) {\n\t\t\t//字典字段，去掉字典翻译文本后缀\n\t\t\tif(column.endsWith(CommonConstant.DICT_TEXT_SUFFIX)) {\n\t\t\t\tcolumn = column.substring(0, column.lastIndexOf(CommonConstant.DICT_TEXT_SUFFIX));\n\t\t\t}\n\n\t\t\t//判断column是不是当前实体的\n\t\t\tlog.debug(\"当前字段有：\"+ allFields);\n\t\t\tif (!allColumnExist(column, allFields)) {\n\t\t\t\tthrow new JeecgBootException(\"请注意，将要排序的列字段不存在：\" + column);\n\t\t\t}\n\n\t\t\t//多字段排序方法没有读取 MybatisPlus 注解 @TableField 里 value 的值\n\t\t\tif (column.contains(\",\")) {\n\t\t\t\tList<String> columnList = Arrays.asList(column.split(\",\"));\n\t\t\t\tString columnStrNew = columnList.stream().map(c -> fieldColumnMap.get(c)).collect(Collectors.joining(\",\"));\n\t\t\t\tif (oConvertUtils.isNotEmpty(columnStrNew)) {\n\t\t\t\t\tcolumn = columnStrNew;\n\t\t\t\t}\n\t\t\t}else{\n\t\t\t\tcolumn = fieldColumnMap.get(column);\n\t\t\t}\n\n\t\t\t//SQL注入check\n\t\t\tSqlInjectionUtil.filterContentMulti(column);\n\n\t\t\t// 排序规则修改\n\t\t\t// 将现有排序 _ 前端传递排序条件{....,column: 'column1,column2',order: 'desc'} 翻译成sql \"column1,column2 desc\"","sourceCodeStart":317,"sourceCodeEnd":353,"githubUrl":"https://github.com/jeecgboot/JeecgBoot/blob/96fb33f5ec68516da0b0147da06b2eb0419e063a/jeecg-boot/jeecg-boot-base-core/src/main/java/org/jeecg/common/system/query/QueryGenerator.java#L317-L353","documentation":"QueryGenerator builds MyBatis-Plus query wrappers including ORDER BY clauses derived from the request's column/page sort parameters. Before translating a sort column to SQL, it validates the column name against the entity's declared fields (allFields). If the requested sort column is not a field of the entity (after stripping the dict-text suffix _dictText and before resolving @TableField mappings), it throws a JeecgBootException to prevent SQL injection via arbitrary column names. This is a security-critical guard.","triggerScenarios":"A list page sends a sort request with a column name that doesn't map to any field on the entity — e.g. a computed/alias column, a typo, a frontend column key that differs from the entity property, or a column that exists only in a SQL view/projection. Also triggered by column names containing the dict-text suffix when the base field is absent.","commonSituations":"Frontend table column `dataIndex`/`field` doesn't match the entity property name; sorting on a virtual/concatenated column; entity refactored (field renamed) but frontend sort config not updated; a column aliased in a custom mapper SQL that isn't a real entity field.","solutions":["Align the frontend sort column name with the entity's property name (or its @TableField value).","If the column is genuinely a computed field, exclude it from sortable columns or map it server-side in the mapper.","Verify the entity class has the field and that allFields population includes it (check field visibility/annotation).","For dict-text columns, ensure the base field (without _dictText suffix) exists on the entity."],"exampleFix":"// before — frontend sorts by a non-existent column\nsortField: 'displayLabel' // not on entity -> throws\n\n// after — sort by the real entity property\nsortField: 'name' // matches entity field","handlingStrategy":"validation","validationCode":"// Frontend: only send sortable columns that map to real entity fields\nconst SORTABLE_FIELDS = ['createTime', 'updateTime', 'id']; // entity-backed\nconst safeSort = SORTABLE_FIELDS.includes(column) ? column : null;","typeGuard":"// Backend: guard before QueryGenerator\nif (!entityFields.contains(sortColumn)) {\n  log.warn(\"Ignoring invalid sort column: {}\", sortColumn);\n  // skip sort instead of throwing\n}","tryCatchPattern":"try {\n  queryWrapper = QueryGenerator.initQueryWrapper(entity, req);\n} catch (e) {\n  // invalid sort column; retry without the sort param\n  req.setColumn(\"\");\n  queryWrapper = QueryGenerator.initQueryWrapper(entity, req);\n}","preventionTips":["Keep frontend sort column keys in sync with entity property names.","Whitelist sortable columns on the backend and ignore unknown ones gracefully.","Strip dict-text suffixes only when the base field exists."],"tags":["backend","mybatis-plus","query","sort","security","jeecg"],"backgroundTag":null,"analyzedSha":"96fb33f5ec68516da0b0147da06b2eb0419e063a","analyzedAt":"2026-08-14T00:04:16.786Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}