baomidou/mybatis-plus · error · IllegalStateException

Duplicate key {}

Error message

Duplicate key {}

What it means

ReflectionKit.excludeOverrideSuperField builds a name-to-Field map of a subclass's declared fields using Collectors.toMap with a merge function that throws IllegalStateException('Duplicate key <field>') on key collision. In Java, one class cannot declare two fields with the same name, so a duplicate here means the input Field[] contains the same field twice — i.e. a class is present multiple times in the type hierarchy traversal (often with interface/default-method or bridge situations in mybatis-plus versions of that era).

Source

Thrown at mybatis-plus-core/src/main/java/com/baomidou/mybatisplus/core/toolkit/ReflectionKit.java:168

                /* 过滤 transient关键字修饰的属性 */
                .filter(f -> !Modifier.isTransient(f.getModifiers()))
                .collect(Collectors.toList());
        });
    }

    /**
     * <p>
     * 排序重置父类属性
     * </p>
     *
     * @param fields         子类属性
     * @param superFieldList 父类属性
     */
    public static Map<String, Field> excludeOverrideSuperField(Field[] fields, List<Field> superFieldList) {
        // 子类属性
        Map<String, Field> fieldMap = Stream.of(fields).collect(toMap(Field::getName, identity(),
            (u, v) -> {
                throw new IllegalStateException("Duplicate key " + u);
            }, LinkedHashMap::new));
        superFieldList.stream().filter(field -> !fieldMap.containsKey(field.getName()))
            .forEach(f -> fieldMap.put(f.getName(), f));
        return fieldMap;
    }

    /**
     * 判断是否为基本类型或基本包装类型
     *
     * @param clazz class
     * @return 是否基本类型或基本包装类型
     */
    @Deprecated
    public static boolean isPrimitiveOrWrapper(Class<?> clazz) {
        Assert.notNull(clazz, "Class must not be null");
        return (clazz.isPrimitive() || PRIMITIVE_WRAPPER_TYPE_MAP.containsKey(clazz));
    }

View on GitHub (pinned to bf67d90747)

Solutions

  1. Upgrade mybatis-plus to the latest patch release — duplicate-field traversal bugs in excludeOverrideSuperField callers were fixed in subsequent versions.
  2. If calling the API directly, deduplicate the Field[] by name (and declaring class) before passing it in.
  3. Inspect the entity hierarchy: remove redundant re-declaration of a field in both a subclass and an interface/default context that triggers duplicate discovery.

Example fix

// before
Map<String, Field> map = ReflectionKit.excludeOverrideSuperField(dupFields, superFields);

// after: dedupe by name first
Map<String, Field> unique = Arrays.stream(dupFields)
    .collect(Collectors.toMap(Field::getName, Function.identity(), (a, b) -> a, LinkedHashMap::new));
Map<String, Field> map = ReflectionKit.excludeOverrideSuperField(unique.values().toArray(new Field[0]), superFields);
Defensive patterns

Strategy: validation

Validate before calling

Set<String> seen = new HashSet<>();
for (Field f : fields) {
    if (!seen.add(f.getName() + "@" + f.getDeclaringClass().getName())) {
        throw new IllegalStateException("duplicate field in input: " + f);
    }
}
Map<String, Field> m = ReflectionKit.excludeOverrideSuperField(fields, superFields);

Type guard

static boolean hasNoDuplicateNames(Field[] fields) {
    Set<String> names = new HashSet<>();
    for (Field f : fields) if (!names.add(f.getName())) return false;
    return true;
}

Try / catch

try {
    Map<String, Field> m = ReflectionKit.excludeOverrideSuperField(fields, superFields);
} catch (IllegalStateException e) {
    throw new IllegalStateException("duplicate field discovered in hierarchy — upgrade mybatis-plus", e);
}

Prevention

When it happens

Trigger: Calling ReflectionKit.excludeOverrideSuperField(fields, superFields) (or mybatis-plus entity metadata init that calls it) where the fields array contains two Field objects with the same name — e.g. getDeclaredFields() of a class that javac duplicated fields for (visibility-bridge generics with covariant overrides), or a user supplying a hand-built Field[] containing duplicates.

Common situations: Entity classes with generic hierarchies where reflection sees duplicate bridge-backed fields; bugs in older mybatis-plus versions (3.4.x era) resolved in later releases; user code copying this helper and feeding it unchecked field lists.

Related errors


AI-assisted analysis of baomidou/mybatis-plus@bf67d90747 (2026-08-14). Data as JSON: /api/errors/0b0b9531f6a7bf41. Report an issue: GitHub.