mybatis/mybatis-3 · error · ExecutorException
Cannot get Configuration as configuration factory was not…
Error message
Cannot get Configuration as configuration factory was not set.
What it means
Thrown when MyBatis must rebuild the lazy-loading machinery of a deserialized object but the configurationFactory was never set. Because LoadPair is serialized without the live Configuration, the only way to get it back is a user-supplied factory class; if lazyLoadingEnabled is true but configurationFactory is omitted in the mybatis-config settings, this fails.
Solutions
- Add <setting name="configurationFactory" value="com.example.MyConfigFactory"/> to the <settings> block of mybatis-config.xml
- Ensure the factory class has a public static Configuration getConfiguration() method returning the live SqlSessionFactory's Configuration
- Pre-load lazy properties before serialization so no Configuration rebuild is needed
- Make the statement parameter object Serializable so the LoadPair actually records the factory at build time
Example fix
<!-- before --> <settings> <setting name="lazyLoadingEnabled" value="true"/> </settings> <!-- after --> <settings> <setting name="lazyLoadingEnabled" value="true"/> <setting name="configurationFactory" value="com.example.MyBatisConfigFactory"/> </settings>
Defensive patterns
Strategy: validation
Validate before calling
// At startup, fail fast if lazy loading is on but the factory is unset
Configuration cfg = sqlSessionFactory.getConfiguration();
if (cfg.isLazyLoadingEnabled() && cfg.getConfigurationFactory() == null) {
throw new IllegalStateException("Set configurationFactory when lazyLoadingEnabled=true");
} Try / catch
try { lazyObj.getLazyProp(); } catch (ExecutorException e) { if (e.getMessage().contains("configuration factory was not set")) { log.error("Config error: add configurationFactory setting", e); } throw e; } Prevention
- Treat lazyLoadingEnabled and configurationFactory as one unit in config reviews
- Add a startup assertion for the settings pair
- Document the factory convention in the project's config template
When it happens
Trigger: A deserialized lazy-loading proxy has load(userObject) called (metaResultObject/resultLoader null), mappedParameter non-null, and LoadPair.getConfiguration() finds this.configurationFactory == null, i.e. <setting name='lazyLoadingEnabled' value='true'/> without <setting name='configurationFactory' value='...'/>.
Common situations: Enabling lazy loading for serializable result objects (session replication, distributed caches) but forgetting the configurationFactory setting; configurationFactory silently not serialized because the parameter object was not Serializable so the field was never populated.
Related errors
- Cannot lazy load property [" + this.property + "] of…
- Cannot get Configuration as factory class [" +…
- Cannot get Configuration as factory method [" +…
- Cannot get Configuration as factory method [" +…
- A query was run and no Result Maps were found for the…
AI-assisted analysis of mybatis/mybatis-3@008069adb1 (2026-08-14).
Data as JSON: /api/errors/ff68aa6aebcee81c.
Report an issue: GitHub.
Appendix: source
Thrown at src/main/java/org/apache/ibatis/executor/loader/ResultLoaderMap.java:227
metaResultObject.getSetterType(this.property), null, null);
}
/*
* We are using a new executor because we may be (and likely are) on a new thread and executors aren't thread
* safe. (Is this sufficient?) A better approach would be making executors thread safe.
*/
if (this.serializationCheck == null) {
final ResultLoader old = this.resultLoader;
this.resultLoader = new ResultLoader(old.configuration, new ClosedExecutor(), old.mappedStatement,
old.parameterObject, old.targetType, old.cacheKey, old.boundSql);
}
this.metaResultObject.setValue(property, this.resultLoader.loadResult());
}
private Configuration getConfiguration() {
if (this.configurationFactory == null) {
throw new ExecutorException("Cannot get Configuration as configuration factory was not set.");
}
Object configurationObject;
try {
final Method factoryMethod = this.configurationFactory.getDeclaredMethod(FACTORY_METHOD);
if (!Modifier.isStatic(factoryMethod.getModifiers())) {
throw new ExecutorException("Cannot get Configuration as factory method [" + this.configurationFactory + "]#["
+ FACTORY_METHOD + "] is not static.");
}
if (!factoryMethod.canAccess(null)) {
configurationObject = AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> {
try {
factoryMethod.setAccessible(true);
return factoryMethod.invoke(null);
} finally {
factoryMethod.setAccessible(false);
}View on GitHub (pinned to 008069adb1)