elunez/eladmin · error · EntityExistException

Menu with title {} existed

Error message

Menu with title {} existed

What it means

EntityExistException thrown in MenuServiceImpl.create when a menu with the same title already exists. menuRepository.findByTitle(resources.getTitle()) is checked before save; any non-null result aborts creation. Menu titles must be globally unique across the whole menu tree, not just among siblings.

Source

Thrown at eladmin-system/src/main/java/me/zhengjie/modules/system/service/impl/MenuServiceImpl.java:124

    @Override
    public List<MenuDto> findByUser(Long currentUserId) {
        String key = CacheKey.MENU_USER + currentUserId;
        List<Menu> menus = redisUtils.getList(key, Menu.class);
        if (CollUtil.isEmpty(menus)){
            List<RoleSmallDto> roles = roleService.findByUsersId(currentUserId);
            Set<Long> roleIds = roles.stream().map(RoleSmallDto::getId).collect(Collectors.toSet());
            LinkedHashSet<Menu> data = menuRepository.findByRoleIdsAndTypeNot(roleIds, 2);
            menus = new ArrayList<>(data);
            redisUtils.set(key, menus, 1, TimeUnit.DAYS);
        }
        return menus.stream().map(menuMapper::toDto).collect(Collectors.toList());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void create(Menu resources) {
        if(menuRepository.findByTitle(resources.getTitle()) != null){
            throw new EntityExistException(Menu.class,"title",resources.getTitle());
        }
        if(StringUtils.isNotBlank(resources.getComponentName())){
            if(menuRepository.findByComponentName(resources.getComponentName()) != null){
                throw new EntityExistException(Menu.class,"componentName",resources.getComponentName());
            }
        }
        if (Long.valueOf(0L).equals(resources.getPid())) {
            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);
        // 更新父节点菜单数目

View on GitHub (pinned to 55fbf70595)

Solutions

  1. Rename the new menu so its title is unique across all menus.
  2. If the duplicate is unintended, delete or rename the existing menu first in Menu Management.
  3. Check existing menus with GET /api/menus (or the lazy-load tree endpoint) before submitting to confirm the title is taken.
  4. When seeding, make the script idempotent: skip creation when findByTitle returns a record.

Example fix

// before: assumes title unique per parent
menuService.create(new Menu("用户管理", pid));

// after: guard against global title duplication
if (menuService.findByTitle(title) == null) {
    menuService.create(new Menu(title, pid));
}
Defensive patterns

Strategy: validation

Validate before calling

// client: check title uniqueness against loaded menu tree
const titles = new Set(allMenus.map(m => m.title));
if (titles.has(form.title)) { alert('菜单标题已存在'); return; }

Try / catch

catch (EntityExistException e) { // message contains 'Menu with title' → prompt user to pick another title }

Prevention

When it happens

Trigger: POST /api/menus with a title that duplicates any existing menu row (e.g. a second menu named '首页' or '用户管理').

Common situations: Re-importing or manually re-adding a menu that already exists in another part of the tree; two developers/seed scripts adding the same menu name; copying a menu configuration between environments that already has it.

Related errors


AI-assisted analysis of elunez/eladmin@55fbf70595 (2026-08-14). Data as JSON: /api/errors/2eeddb6c7e31615a. Report an issue: GitHub.