mybatis/mybatis-3 · error · IllegalArgumentException

Parameter 'transactionFactory' must not be null

Error message

Parameter 'transactionFactory' must not be null

What it means

Environment's constructor throws IllegalArgumentException when transactionFactory is null. MyBatis needs a TransactionFactory (JdbcTransactionFactory or ManagedTransactionFactory) to open transactions for the environment, so it refuses null after the id check.

Source

Thrown at src/main/java/org/apache/ibatis/mapping/Environment.java:35

import javax.sql.DataSource;

import org.apache.ibatis.transaction.TransactionFactory;

/**
 * @author Clinton Begin
 */
public final class Environment {
  private final String id;
  private final TransactionFactory transactionFactory;
  private final DataSource dataSource;

  public Environment(String id, TransactionFactory transactionFactory, DataSource dataSource) {
    if (id == null) {
      throw new IllegalArgumentException("Parameter 'id' must not be null");
    }
    if (transactionFactory == null) {
      throw new IllegalArgumentException("Parameter 'transactionFactory' must not be null");
    }
    this.id = id;
    if (dataSource == null) {
      throw new IllegalArgumentException("Parameter 'dataSource' must not be null");
    }
    this.transactionFactory = transactionFactory;
    this.dataSource = dataSource;
  }

  public static class Builder {
    private final String id;
    private TransactionFactory transactionFactory;
    private DataSource dataSource;

    public Builder(String id) {
      this.id = id;
    }

View on GitHub (pinned to 008069adb1)

Solutions

  1. Pass a concrete factory: new JdbcTransactionFactory() (or ManagedTransactionFactory for container-managed transactions).
  2. If built by DI, verify the TransactionFactory bean exists and is injected.
  3. Add a null check earlier at the config-loading layer with a clearer message about which setting is missing.

Example fix

// before
Environment env = new Environment("dev", null, dataSource);

// after
Environment env = new Environment("dev", new JdbcTransactionFactory(), dataSource);
Defensive patterns

Strategy: validation

Validate before calling

TransactionFactory txFactory = Objects.requireNonNull(txFactory, "TransactionFactory not wired");
new Environment("dev", txFactory, ds);

Prevention

When it happens

Trigger: new Environment("dev", null, dataSource) — typically the factory variable was never initialized or the wrong branch of a conditional left it null.

Common situations: Switching from XML to Java-based config and forgetting new JdbcTransactionFactory(); DI containers not wiring the field; copy-paste of an Environment construction with the factory argument dropped.

Related errors


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