{"record":{"id":"33e561b3c91c3dd7","repo":"mybatis/mybatis-3","slug":"resultloader-could-not-load-lazily-datasource-wa","errorCode":null,"errorMessage":"ResultLoader could not load lazily.  DataSource was not configured.","messagePattern":"ResultLoader could not load lazily\\.  DataSource was not configured\\.","errorType":"exception","errorClass":"ExecutorException","httpStatus":null,"severity":"error","filePath":"src/main/java/org/apache/ibatis/executor/loader/ResultLoader.java","lineNumber":98,"sourceCode":"    }\n    try {\n      return localExecutor.query(mappedStatement, parameterObject, RowBounds.DEFAULT, Executor.NO_RESULT_HANDLER,\n          cacheKey, boundSql);\n    } finally {\n      if (localExecutor != executor) {\n        localExecutor.close(false);\n      }\n    }\n  }\n\n  private Executor newExecutor() {\n    final Environment environment = configuration.getEnvironment();\n    if (environment == null) {\n      throw new ExecutorException(\"ResultLoader could not load lazily.  Environment was not configured.\");\n    }\n    final DataSource ds = environment.getDataSource();\n    if (ds == null) {\n      throw new ExecutorException(\"ResultLoader could not load lazily.  DataSource was not configured.\");\n    }\n    final TransactionFactory transactionFactory = environment.getTransactionFactory();\n    final Transaction tx = transactionFactory.newTransaction(ds, null, false);\n    return configuration.newExecutor(tx, ExecutorType.SIMPLE);\n  }\n\n  public boolean wasNull() {\n    return resultObject == null;\n  }\n\n}\n","sourceCodeStart":80,"sourceCodeEnd":110,"githubUrl":"https://github.com/mybatis/mybatis-3/blob/008069adb1b089579b5dcba87ee591908b263274/src/main/java/org/apache/ibatis/executor/loader/ResultLoader.java#L80-L110","documentation":"After confirming an Environment exists, ResultLoader.newExecutor also requires it to carry a DataSource, because a lazy load must open its own connection/transaction. A null DataSource inside the Environment means no connection can be obtained, so this ExecutorException is thrown.","triggerScenarios":"new Environment(id, transactionFactory, null) — constructing the Environment with a null DataSource; custom Environment subclasses returning null from getDataSource(); partially initialized test environments.","commonSituations":"Programmatic configuration where the DataSource wiring was skipped or deferred; copy-pasted Environment construction; mocking the Environment in tests.","solutions":["Pass a real DataSource when constructing the Environment","Verify the DataSource bean/lookup is initialized before the SqlSessionFactory is built","In tests, supply an embedded DataSource (H2) instead of null"],"exampleFix":"// before\nEnvironment env = new Environment(\"dev\", new JdbcTransactionFactory(), null);\n\n// after\nEnvironment env = new Environment(\"dev\", new JdbcTransactionFactory(), dataSource);","handlingStrategy":"validation","validationCode":"// Verify the Environment carries a DataSource before enabling lazy loading\nEnvironment env = configuration.getEnvironment();\nif (env == null || env.getDataSource() == null) {\n  throw new IllegalStateException(\"Lazy loading requires an Environment with a non-null DataSource\");\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never construct Environment with a null DataSource","Initialize the DataSource bean before the SqlSessionFactory in your DI container"],"tags":["lazy-loading","datasource","configuration"],"backgroundTag":null,"analyzedSha":"008069adb1b089579b5dcba87ee591908b263274","analyzedAt":"2026-08-14T13:07:10.264Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}