baomidou/mybatis-plus · error · BuilderException

Could not find a statement annotation that correspond a curr

Error message

Could not find a statement annotation that correspond a current database or default statement on method '%s.%s'. Current database id is [%s].

What it means

Thrown when a mapper method carries statement annotations but none matches the active databaseId. The builder found annotations (statementAnnotations is non-empty), but neither the current databaseId nor the annotation-default (empty string) key is present, and errorIfNoMatch is on, so the method cannot be bound to any statement for this database.

Source

Thrown at mybatis-plus-core/src/main/java/com/baomidou/mybatisplus/core/MybatisMapperAnnotationBuilder.java:618

                                                                                     Collection<Class<? extends Annotation>> targetTypes) {
        String databaseId = configuration.getDatabaseId();
        Map<String, AnnotationWrapper> statementAnnotations = targetTypes.stream()
            .flatMap(x -> Arrays.stream(method.getAnnotationsByType(x))).map(AnnotationWrapper::new)
            .collect(Collectors.toMap(AnnotationWrapper::getDatabaseId, x -> x, (existing, duplicate) -> {
                throw new BuilderException(
                    String.format("Detected conflicting annotations '%s' and '%s' on '%s'.", existing.getAnnotation(),
                        duplicate.getAnnotation(), method.getDeclaringClass().getName() + "." + method.getName()));
            }));
        AnnotationWrapper annotationWrapper = null;
        if (databaseId != null) {
            annotationWrapper = statementAnnotations.get(databaseId);
        }
        if (annotationWrapper == null) {
            annotationWrapper = statementAnnotations.get("");
        }
        if (errorIfNoMatch && annotationWrapper == null && !statementAnnotations.isEmpty()) {
            // Annotations exist, but there is no matching one for the specified databaseId
            throw new BuilderException(String.format(
                "Could not find a statement annotation that correspond a current database or default statement on method '%s.%s'. Current database id is [%s].",
                method.getDeclaringClass().getName(), method.getName(), databaseId));
        }
        return Optional.ofNullable(annotationWrapper);
    }

    public static Class<?> getMethodReturnType(String mapperFqn, String localStatementId) {
        if (mapperFqn == null || localStatementId == null) {
            return null;
        }
        try {
            Class<?> mapperClass = Resources.classForName(mapperFqn);
            for (Method method : mapperClass.getMethods()) {
                if (method.getName().equals(localStatementId) && canHaveStatement(method)) {
                    return getReturnType(method, mapperClass);
                }
            }
        } catch (ClassNotFoundException e) {

View on GitHub (pinned to bf67d90747)

Solutions

  1. Add a default (no databaseId) @Select variant on the method so a statement always exists regardless of the active database.
  2. Align the DatabaseIdProvider configuration with the databaseId values used in the annotations (verify the value returned for your DataSource).
  3. If multi-DB support is not needed, strip databaseId attributes from the annotations.

Example fix

// before
@Select(databaseId = "oracle", value = "SELECT 1 FROM dual")
int ping();

// after
@Select(databaseId = "oracle", value = "SELECT 1 FROM dual")
@Select(value = "SELECT 1")
int ping();
Defensive patterns

Strategy: validation

Validate before calling

// ensure every annotated method has a statement matching the active databaseId
String currentDbId = factory.getConfiguration().getDatabaseId();
for (java.lang.reflect.Method m : mapper.getMethods()) {
    boolean hasDefault = false, hasCurrent = false;
    for (java.lang.annotation.Annotation a : m.getAnnotations()) {
        try {
            String dbId = (String) a.annotationType().getMethod("databaseId").invoke(a);
            if (dbId == null || dbId.isEmpty()) hasDefault = true;
            if (currentDbId != null && currentDbId.equals(dbId)) hasCurrent = true;
        } catch (NoSuchMethodException ignored) { }
    }
    // if any statement annotation exists but neither flag set -> will fail
}

Try / catch

Catch BuilderException containing 'Could not find a statement annotation'; add a default-keyed annotation variant or fix DatabaseIdProvider settings.

Prevention

When it happens

Trigger: All @Select/@Insert annotations on a method declare databaseId = "oracle" while the runtime Configuration.getDatabaseId() returns "mysql" (or null with no default-keyed annotation present).

Common situations: Running the app against a different database than the annotations target; DatabaseIdProvider not configured so databaseId is null while annotations only have vendor-qualified variants; changing the databaseIdProvider properties without updating mapper annotations.

Related errors


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