elunez/eladmin · error · BadRequestException
上级不能为自己
Error message
上级不能为自己
What it means
BadRequestException thrown in MenuServiceImpl.update when a menu's pid (parent id) equals its own id. Setting a menu as its own parent would create a self-referencing cycle in the menu tree, breaking tree building, lazy loading, and subCount maintenance.
Source
Thrown at eladmin-system/src/main/java/me/zhengjie/modules/system/service/impl/MenuServiceImpl.java:150
resources.setPid(null);
}
if(resources.getIFrame()){
if (!(resources.getPath().toLowerCase().startsWith(HTTP_PRE)||resources.getPath().toLowerCase().startsWith(HTTPS_PRE))) {
throw new BadRequestException(BAD_REQUEST);
}
}
menuRepository.save(resources);
// 计算子节点数目
resources.setSubCount(0);
// 更新父节点菜单数目
updateSubCnt(resources.getPid());
}
@Override
@Transactional(rollbackFor = Exception.class)
public void update(Menu resources) {
if(resources.getId().equals(resources.getPid())) {
throw new BadRequestException("上级不能为自己");
}
Menu menu = menuRepository.findById(resources.getId()).orElseGet(Menu::new);
ValidationUtil.isNull(menu.getId(),"Permission","id",resources.getId());
if(resources.getIFrame()){
if (!(resources.getPath().toLowerCase().startsWith(HTTP_PRE)||resources.getPath().toLowerCase().startsWith(HTTPS_PRE))) {
throw new BadRequestException(BAD_REQUEST);
}
}
Menu menu1 = menuRepository.findByTitle(resources.getTitle());
if(menu1 != null && !menu1.getId().equals(menu.getId())){
throw new EntityExistException(Menu.class,"title",resources.getTitle());
}
if(resources.getPid().equals(0L)){
resources.setPid(null);
}View on GitHub (pinned to 55fbf70595)
Solutions
- Pick a different parent (or clear pid to null/0 for a root menu) before saving.
- Fix the front-end parent selector to filter out the current menu node from the candidate parent tree.
- Validate id !== pid client-side before issuing the PUT.
Example fix
// before menu.setPid(menu.getId()); // self-parent rejected // after: root-level menu menu.setPid(null); // or 0L, which the service converts to null
Defensive patterns
Strategy: validation
Validate before calling
if (Objects.equals(form.id, form.pid)) { alert('上级菜单不能为自身'); return; } Type guard
const isValidParent = (id: number, pid: number | null) => pid === null || pid !== id;
Prevention
- Exclude the editing node from the parent tree selector
- Clear pid to 0/null when making the menu a root
- Validate id !== pid in the form schema before submit
When it happens
Trigger: PUT /api/menus where the request body's id and pid are the same value (e.g. dragging a menu node onto itself in the tree editor, or a form that defaults pid to the menu's own id).
Common situations: Front-end tree selector not excluding the node being edited; importing edited menu JSON where pid was copied from id; drag-and-drop tree plugins firing a drop event on the same node.
Related errors
- 外链必须以http://或者https://开头
- 没有这个选项
- A new menu cannot already have an ID
- Menu with title {} existed
- Menu with componentName {} existed
AI-assisted analysis of elunez/eladmin@55fbf70595 (2026-08-14).
Data as JSON: /api/errors/728538281a7360a2.
Report an issue: GitHub.