mybatis/mybatis-3 · critical · BindingException

Invalid bound statement (not found): {mapperInterface}.{meth

Error message

Invalid bound statement (not found): {mapperInterface}.{methodName}

What it means

The mapper method could not be matched to any MappedStatement in the Configuration. MyBatis looks up statements by fully-qualified name (interface FQN + '.' + method name, walking parent interfaces), and throws this BindingException when nothing is registered. It is the single most common MyBatis startup/first-call error.

Source

Thrown at src/main/java/org/apache/ibatis/binding/MapperMethod.java:228

        throw new BindingException("Parameter '" + key + "' not found. Available parameters are " + keySet());
      }
      return super.get(key);
    }

  }

  public static class SqlCommand {

    private final String name;
    private final SqlCommandType type;

    public SqlCommand(Configuration configuration, Class<?> mapperInterface, Method method) {
      final String methodName = method.getName();
      final Class<?> declaringClass = method.getDeclaringClass();
      MappedStatement ms = resolveMappedStatement(mapperInterface, methodName, declaringClass, configuration);
      if (ms == null) {
        if (method.getAnnotation(Flush.class) == null) {
          throw new BindingException(
              "Invalid bound statement (not found): " + mapperInterface.getName() + "." + methodName);
        }
        name = null;
        type = SqlCommandType.FLUSH;
      } else {
        name = ms.getId();
        type = ms.getSqlCommandType();
        if (type == SqlCommandType.UNKNOWN) {
          throw new BindingException("Unknown execution method for: " + name);
        }
      }
    }

    public String getName() {
      return name;
    }

    public SqlCommandType getType() {

View on GitHub (pinned to 008069adb1)

Solutions

  1. Verify the XML namespace equals the mapper interface fully-qualified name and the statement id equals the method name
  2. Ensure the XML file is actually loaded: add it to mybatis-config.xml <mappers>, set mybatis.mapper-locations in Spring Boot, or annotate the method with @Select/@Insert
  3. Check build packaging: Maven needs <resource> entries to copy *.xml from src/main/java
  4. If using annotations only, confirm the mapper interface is registered (addMapper / @MapperScan) and there are no typos in method names

Example fix

<!-- before -->
<mapper namespace="com.example.UserMapper">
  <select id="findUser" ...>
<!-- interface: com.example.UserDao#findUser -->
<!-- after -->
<mapper namespace="com.example.UserDao">
  <select id="findUser" ...>
Defensive patterns

Strategy: validation

Validate before calling

Configuration cfg = sqlSessionFactory.getConfiguration();
boolean bound = cfg.hasStatement("com.example.UserMapper.findUsers");
if (!bound) { /* register or fail with clear message */ }

Prevention

When it happens

Trigger: No XML <select id="..."> with matching namespace and id; annotation method missing; statement XML file not loaded (not in mapperLocations, not in mybatis-config); interface and XML namespace mismatch; using MyBatis with Spring and the mapper scanned but its XML not on the classpath; method name typo between interface and XML id.

Common situations: Maven/Gradle build filtering out XML files from src/main/java; namespace not equal to the interface FQN; forgetting to register the mapper in mybatis-config.xml <mappers>; in mybatis-spring, MapperScan covering a different package than the XML namespace; inner-Interface methods not resolvable through the parent chain.

Related errors


AI-assisted analysis of mybatis/mybatis-3@008069adb1 (2026-08-14). Data as JSON: /api/errors/f4b0b912e32992a7. Report an issue: GitHub.