hs-web/hsweb-framework · error · ValidationException
error.tree_entity_parent_id_not_exist
error.tree_entity_parent_id_not_exist
Error message
error.tree_entity_parent_id_not_exist
What it means
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.
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).
Example fix
// before
[{"id":"c1","parentId":"p_missing"}]
// after
[{"id":"p1","parentId":null},{"id":"c1","parentId":"p1"}] Defensive patterns
Strategy: validation
Validate before calling
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())); } Try / catch
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); Prevention
- Always submit parent rows together with children
- Check parentId references exist before delete/save
- Standardize ID types (String) across client and server
When it happens
Trigger: 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.
Common situations: 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.
Understand the failure class
Background: "Not found" and "does not exist" errors: why "Task not found", "No such folder", and "Can't find" fire when a lookup comes back empty — this error's family across 14 libraries.
Related errors
- error.tree_entity_cyclic_dependency
- parentId
- error.page_size_exceeded
- undefined column [" + column + "]
- error.illegal_column_name
AI-assisted analysis of hs-web/hsweb-framework@b2cfc85a57 (2026-09-13).
Data as JSON: /api/errors/ff6593ee2db5335e.
Report an issue: GitHub.
Appendix: source
Thrown at hsweb-commons/hsweb-commons-crud/src/main/java/org/hswebframework/web/crud/service/TreeSortServiceHelper.java:169
Set<PK> readyToCheck = thisTime
.values()
.stream()
.map(TreeSupportEntity::getParentId)
.filter(e -> !ObjectUtils.isEmpty(e) && !allData.containsKey(e))
.collect(Collectors.toSet());
if (readyToCheck.isEmpty()) {
return Mono.empty();
}
return queryById(readyToCheck)
.doOnNext(e -> {
allData.put(e.getId(), e);
readyToCheck.remove(e.getId());
})
.then(Mono.fromRunnable(() -> {
if (!readyToCheck.isEmpty()) {
throw new ValidationException(
"error.tree_entity_parent_id_not_exist",
Collections.singletonList(
new ValidationException.Detail(
"parentId",
"error.tree_entity_parent_id_not_exist",
readyToCheck))
);
}
initChildren();
}));
}
private void refactorPath() {
Function<PK, Collection<E>> childGetter
= id -> childrenMapping
.getOrDefault(id, Collections.emptyMap())
.values();
View on GitHub (pinned to b2cfc85a57)