mybatis/mybatis-3 · error · DataSourceException

Unknown DataSource property: ${propertyName}

Error message

Unknown DataSource property: ${propertyName}

What it means

UnpooledDataSourceFactory.setProperties() maps each configuration property onto the UnpooledDataSource bean via reflection. Properties starting with 'driver.' are collected as raw driver properties; any other property must have a corresponding setter on UnpooledDataSource (driver, url, username, password, autoCommit, defaultAutoCommit, defaultTransactionIsolationLevel, defaultNetworkTimeout, driverClassLoader, driverProperties, loginTimeout). Anything else throws DataSourceException 'Unknown DataSource property: <name>'.

Source

Thrown at src/main/java/org/apache/ibatis/datasource/unpooled/UnpooledDataSourceFactory.java:55

  public UnpooledDataSourceFactory() {
    this.dataSource = new UnpooledDataSource();
  }

  @Override
  public void setProperties(Properties properties) {
    Properties driverProperties = new Properties();
    MetaObject metaDataSource = SystemMetaObject.forObject(dataSource);
    for (Object key : properties.keySet()) {
      String propertyName = (String) key;
      if (propertyName.startsWith(DRIVER_PROPERTY_PREFIX)) {
        String value = properties.getProperty(propertyName);
        driverProperties.setProperty(propertyName.substring(DRIVER_PROPERTY_PREFIX_LENGTH), value);
      } else if (metaDataSource.hasSetter(propertyName)) {
        String value = (String) properties.get(propertyName);
        Object convertedValue = convertValue(metaDataSource, propertyName, value);
        metaDataSource.setValue(propertyName, convertedValue);
      } else {
        throw new DataSourceException("Unknown DataSource property: " + propertyName);
      }
    }
    if (driverProperties.size() > 0) {
      metaDataSource.setValue("driverProperties", driverProperties);
    }
  }

  @Override
  public DataSource getDataSource() {
    return dataSource;
  }

  private Object convertValue(MetaObject metaDataSource, String propertyName, String value) {
    Object convertedValue = value;
    Class<?> targetType = metaDataSource.getSetterType(propertyName);
    if (targetType == Integer.class || targetType == int.class) {
      convertedValue = Integer.valueOf(value);
    } else if (targetType == Long.class || targetType == long.class) {

View on GitHub (pinned to 008069adb1)

Solutions

  1. Fix or remove the offending property — the message names it exactly
  2. Use only supported setters: driver, url, username, password, autoCommit, defaultTransactionIsolationLevel, defaultNetworkTimeout, loginTimeout
  3. Driver-specific connection settings must go through the 'driver.' prefix (e.g., driver.encoding=UTF8) which becomes java.util.Properties passed to DriverManager
  4. If you need richer options (pool size, cachePrepStmts...), switch to type="POOLED" pool.* properties or plug in an external pool via a custom DataSourceFactory

Example fix

<!-- before -->
<dataSource type="UNPOOLED">
  <property name="jdbcUrl" value="jdbc:mysql://db/app"/> <!-- wrong: use 'url' -->
  <property name="user" value="app"/>                    <!-- wrong: use 'username' -->
</dataSource>

<!-- after -->
<dataSource type="UNPOOLED">
  <property name="url" value="jdbc:mysql://db/app"/>
  <property name="username" value="app"/>
  <property name="driver.characterEncoding" value="utf8"/>
</dataSource>
Defensive patterns

Strategy: validation

Validate before calling

// Validate config keys against the known UNPOOLED setter set before passing to MyBatis:
Set<String> allowed = Set.of("driver","url","username","password","autoCommit",
    "defaultAutoCommit","defaultTransactionIsolationLevel","defaultNetworkTimeout",
    "driverClassLoader","driverProperties","loginTimeout");
for (String k : props.stringPropertyNames()) {
  if (!k.startsWith("driver.") && !allowed.contains(k))
    throw new IllegalArgumentException("Unknown DataSource property: " + k);
}

Try / catch

try {
  factory.setProperties(props);
} catch (DataSourceException e) {
  if (e.getMessage().startsWith("Unknown DataSource property:")) {
    // message names the bad key: fix or move it under the 'driver.' prefix
  } else throw e;
}

Prevention

When it happens

Trigger: Typing a property in the UNPOOLED dataSource config that has no setter (e.g., 'user' instead of 'username', 'jdbcUrl' instead of 'url', pool settings like 'maximumPoolSize' that only exist on POOLED or external pools); passing HikariCP/DBCP option names to the built-in factories; misspelled property names in mybatis-config.xml or a Properties object passed to a DataSourceFactory.

Common situations: Copy-pasting datasource config from HikariCP/DBCP/Tomcat JDBC examples into MyBatis' built-in factories; assuming 'user' works (it is 'username'); putting JDBC URL parameters as top-level properties instead of inside the url value or under driver. prefix.

Related errors


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