{"record":{"id":"24551a3e68fc1e65","repo":"baomidou/mybatis-plus","slug":"error","errorCode":null,"errorMessage":"不支持的方法!","messagePattern":"不支持的方法!","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"mybatis-plus-extension/src/main/java/com/baomidou/mybatisplus/extension/repository/IRepository.java","lineNumber":74,"sourceCode":"    /**\n     * 根据 ID 删除\n     *\n     * @param id 主键ID\n     */\n    default boolean removeById(Serializable id) {\n        return SqlHelper.retBool(getBaseMapper().deleteById(id));\n    }\n\n    /**\n     * 根据 ID 删除\n     *\n     * @param id      主键(类型必须与实体类型字段保持一致)\n     * @param useFill 是否启用填充(为true的情况,会将入参转换实体进行delete删除)\n     * @return 删除结果\n     * @since 3.5.0\n     */\n    default boolean removeById(Serializable id, boolean useFill) {\n        throw new UnsupportedOperationException(\"不支持的方法!\");\n    }\n\n    /**\n     * 根据实体(ID)删除\n     *\n     * @param entity 实体\n     * @since 3.4.4\n     */\n    default boolean removeById(T entity) {\n        return SqlHelper.retBool(getBaseMapper().deleteById(entity));\n    }\n\n    /**\n     * 根据 columnMap 条件，删除记录\n     *\n     * @param columnMap 表字段 map 对象\n     */\n    default boolean removeByMap(Map<String, Object> columnMap) {","sourceCodeStart":56,"sourceCodeEnd":92,"githubUrl":"https://github.com/baomidou/mybatis-plus/blob/bf67d907478c724120bf76292da54abf9e73c2b3/mybatis-plus-extension/src/main/java/com/baomidou/mybatisplus/extension/repository/IRepository.java#L56-L92","documentation":"IRepository.removeById(Serializable id, boolean useFill) defaults to throwing UnsupportedOperationException('不支持的方法!' — 'Unsupported method!'). The base IRepository interface only implements the common path; the fill-aware variant (which converts the id to an entity to run fill logic before delete) is only meaningful for implementations backed by a full ServiceImpl-style repository. Calling it on the default interface, or on a custom implementation that does not override it, explodes.","triggerScenarios":"Holding an IRepository (or a custom implementation of it) and calling removeById(id, true) — the two-argument fill variant — without the concrete class overriding that default method. Introduced in 3.5.0; implementations like the standard repository/service impl override it, minimal custom ones do not.","commonSituations":"Custom IRepository implementations (e.g. a thin repository over a base mapper) written against an older API surface, then new code calls the 3.5.0 fill variant; switching a bean from ServiceImpl to a hand-written repository loses the override; mocking IRepository in tests without stubbing the default method (some mock libs invoke real defaults).","solutions":["Override removeById(Serializable id, boolean useFill) in your IRepository implementation, implementing the fill path (convert id to entity, apply meta-object fill, delete).","Or call the supported variant removeById(id) (single-argument) which routes to getBaseMapper().deleteById(id) directly.","If fill-on-delete is required, extend the provided ServiceImpl/repository base class that already implements it.","In tests, use Mockito with CALLS_REAL_METHODS awareness or explicitly stub the two-argument variant."],"exampleFix":"// before: custom repo does not override fill variant\npublic class UserRepository implements IRepository<User> {\n    // removeById(id, useFill) inherited default -> UnsupportedOperationException\n}\n\n// after: override it\npublic class UserRepository implements IRepository<User> {\n    @Override\n    public boolean removeById(Serializable id, boolean useFill) {\n        if (!useFill) return SqlHelper.retBool(getBaseMapper().deleteById(id));\n        User entity = getById(id);\n        return SqlHelper.retBool(getBaseMapper().deleteById(entity));\n    }\n}","handlingStrategy":"type-guard","validationCode":"IRepository<User> repo = acquireRepository();\nboolean fillVariantSupported;\ntry {\n    repo.getClass().getMethod(\"removeById\", Serializable.class, boolean.class)\n        .getDeclaringClass();\n    fillVariantSupported = !IRepository.class.equals(\n        repo.getClass().getMethod(\"removeById\", Serializable.class, boolean.class).getDeclaringClass());\n} catch (NoSuchMethodException e) { fillVariantSupported = false; }\nif (!fillVariantSupported) repo.removeById(id); // use supported single-arg variant","typeGuard":"static boolean supportsRemoveByIdWithFill(Object repo) {\n    try {\n        Method m = repo.getClass().getMethod(\"removeById\", Serializable.class, boolean.class);\n        return !m.getDeclaringClass().isInterface(); // real override, not default\n    } catch (NoSuchMethodException e) {\n        return false;\n    }\n}","tryCatchPattern":"try {\n    repository.removeById(id, true);\n} catch (UnsupportedOperationException e) {\n    repository.removeById(id); // fall back to the always-supported variant\n}","preventionTips":["Override the two-argument removeById in custom IRepository implementations, or extend the provided base classes.","Prefer the single-argument removeById unless fill-on-delete is explicitly required."],"tags":["repository","api-contract","default-method","upgrade"],"backgroundTag":null,"analyzedSha":"bf67d907478c724120bf76292da54abf9e73c2b3","analyzedAt":"2026-08-14T15:17:09.543Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}