{"record":{"id":"ff6593ee2db5335e","repo":"hs-web/hsweb-framework","slug":"error-tree-entity-parent-id-not-exist","errorCode":"error.tree_entity_parent_id_not_exist","errorMessage":"error.tree_entity_parent_id_not_exist","messagePattern":"error\\.tree_entity_parent_id_not_exist","errorType":"validation","errorClass":"ValidationException","httpStatus":400,"severity":"error","filePath":"hsweb-commons/hsweb-commons-crud/src/main/java/org/hswebframework/web/crud/service/TreeSortServiceHelper.java","lineNumber":169,"sourceCode":"\n        Set<PK> readyToCheck = thisTime\n            .values()\n            .stream()\n            .map(TreeSupportEntity::getParentId)\n            .filter(e -> !ObjectUtils.isEmpty(e) && !allData.containsKey(e))\n            .collect(Collectors.toSet());\n\n        if (readyToCheck.isEmpty()) {\n            return Mono.empty();\n        }\n        return queryById(readyToCheck)\n            .doOnNext(e -> {\n                allData.put(e.getId(), e);\n                readyToCheck.remove(e.getId());\n            })\n            .then(Mono.fromRunnable(() -> {\n                if (!readyToCheck.isEmpty()) {\n                    throw new ValidationException(\n                        \"error.tree_entity_parent_id_not_exist\",\n                        Collections.singletonList(\n                            new ValidationException.Detail(\n                                \"parentId\",\n                                \"error.tree_entity_parent_id_not_exist\",\n                                readyToCheck))\n                    );\n                }\n                initChildren();\n            }));\n    }\n\n    private void refactorPath() {\n        Function<PK, Collection<E>> childGetter\n            = id -> childrenMapping\n            .getOrDefault(id, Collections.emptyMap())\n            .values();\n","sourceCodeStart":151,"sourceCodeEnd":187,"githubUrl":"https://github.com/hs-web/hsweb-framework/blob/b2cfc85a57c70bf5b5cf6e7edae2d37102652ec8/hsweb-commons/hsweb-commons-crud/src/main/java/org/hswebframework/web/crud/service/TreeSortServiceHelper.java#L151-L187","documentation":"TreeSortServiceHelper verifies that every non-root entity's parentId refers to an entity present in the submitted data set. It collects IDs of entities whose parents were not yet seen into readyToCheck; if any remain after processing all data, a ValidationException with code `error.tree_entity_parent_id_not_exist` is thrown (reactive, inside Mono.fromRunnable) listing the missing parent IDs.","triggerScenarios":"Saving a batch of tree entities where at least one entity's parentId does not match any ID in the batch (and is not validated as an existing DB row per the helper's load path), causing readyToCheck to be non-empty after the flux completes.","commonSituations":"Client submits children with parentIds pointing to rows not included in the payload; stale parentId after the parent was deleted; ID type/format mismatches (e.g. string vs number) so lookups never match.","solutions":["Include the parent entity in the same submitted batch, or set parentId to null/empty for roots.","Ensure the referenced parent actually exists and was not deleted.","Verify parentId values use the same ID type/format as entity IDs (no padding/quoting differences)."],"exampleFix":"// before\n[{\"id\":\"c1\",\"parentId\":\"p_missing\"}]\n// after\n[{\"id\":\"p1\",\"parentId\":null},{\"id\":\"c1\",\"parentId\":\"p1\"}]","handlingStrategy":"validation","validationCode":"Set<PK> ids = list.stream().map(E::getId).collect(Collectors.toSet()); List<E> orphans = list.stream().filter(e -> e.getParentId() != null && !ids.contains(e.getParentId())).collect(Collectors.toList()); if (!orphans.isEmpty()) { throw new ValidationException(\"parentId\", \"parents not found: \" + orphans.stream().map(E::getParentId).collect(Collectors.toSet())); }","typeGuard":null,"tryCatchPattern":"flux.then().onErrorMap(ValidationException.class, e -> \"error.tree_entity_parent_id_not_exist\".equals(e.getCode()) ? new BadRequestException(\"parent ids do not exist: \" + e.getDetails()) : e);","preventionTips":["Always submit parent rows together with children","Check parentId references exist before delete/save","Standardize ID types (String) across client and server"],"tags":["tree-structure","foreign-key","validation","reactive"],"backgroundTag":"entity-not-found","analyzedSha":"b2cfc85a57c70bf5b5cf6e7edae2d37102652ec8","analyzedAt":"2026-09-13T09:05:02.172Z","contentChangedAt":"2026-09-13T09:05:02.172Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}