baomidou/mybatis-plus · error · MybatisPlusException
Unable to retrieve the mapperInterface and sqlSession proper
Error message
Unable to retrieve the mapperInterface and sqlSession properties from %s
What it means
MapperProxyMetadata was constructed from a MetaObject that does not expose 'mapperInterface' and 'sqlSession' getters — i.e. the wrapped object is not (or cannot be reflected as) a MyBatis MapperProxy. This utility extracts the two fields every MapperProxy carries, so anything else is a programming error.
Source
Thrown at mybatis-plus-core/src/main/java/com/baomidou/mybatisplus/core/metadata/MapperProxyMetadata.java:39
/**
* Mapper代理属性
*
* @author nieqiurong
* @see com.baomidou.mybatisplus.core.override.MybatisMapperProxy
* @see org.apache.ibatis.binding.MapperProxy
* @since 3.5.12
*/
@SuppressWarnings("LombokGetterMayBeUsed")
public class MapperProxyMetadata {
private final SqlSession sqlSession;
private final Class<?> mapperInterface;
public MapperProxyMetadata(MetaObject metaObject) {
if (!metaObject.hasGetter("mapperInterface") || !metaObject.hasGetter("sqlSession")) {
throw new MybatisPlusException("Unable to retrieve the mapperInterface and sqlSession properties from " + metaObject.getOriginalObject());
}
this.mapperInterface = (Class<?>) metaObject.getValue("mapperInterface");
this.sqlSession = (SqlSession) metaObject.getValue("sqlSession");
}
public Class<?> getMapperInterface() {
return mapperInterface;
}
public SqlSession getSqlSession() {
return sqlSession;
}
@Override
public String toString() {
return "MapperProxy{" +
"mapperInterface=" + mapperInterface +
", sqlSession=" + sqlSession +View on GitHub (pinned to bf67d90747)
Solutions
- Unwrap to the actual MapperProxy before building metadata: get the InvocationHandler of the JDK proxy first
- Check metaObject.hasGetter("mapperInterface") && hasGetter("sqlSession") before constructing, or extract h from Proxy.getInvocationHandler(mapper) and pass that
- If you wrapped mappers in another proxy layer, unwrap iteratively until the handler is a MapperProxy
Example fix
// before Object target = AopProxyUtils.getSingletonTarget(mapper); new MapperProxyMetadata(SystemMetaObject.forObject(target)); // not a MapperProxy // after Object handler = Proxy.getInvocationHandler(mapper); new MapperProxyMetadata(SystemMetaObject.forObject(handler)); // MapperProxy exposes both getters
Defensive patterns
Strategy: type-guard
Validate before calling
Object h = mapper instanceof Proxy ? Proxy.getInvocationHandler(mapper) : mapper;
if (!(h instanceof MapperProxy)) throw new IllegalArgumentException("Not a MyBatis mapper proxy"); Type guard
static MapperProxyMetadata metadataOf(Object mapper) {
Object h = mapper;
while (h instanceof Proxy) h = Proxy.getInvocationHandler(h);
MetaObject mo = SystemMetaObject.forObject(h);
if (mo.hasGetter("mapperInterface") && mo.hasGetter("sqlSession")) {
return new MapperProxyMetadata(mo);
}
return null; // caller falls back
} Try / catch
catch MybatisPlusException and treat the object as non-mapper: log.debug("Not a MapperProxy: {}", obj.getClass()); skip metadata extraction. Prevention
- Always unwrap JDK proxies to their InvocationHandler before reflecting on mapper internals
- Guard with hasGetter checks (as the type-guard above) before constructing MapperProxyMetadata
- Keep framework code decoupled from MapperProxy layout where a public API exists
When it happens
Trigger: Framework/plugin code calling new MapperProxyMetadata(SystemMetaObject.forObject(obj)) where obj is a plain bean, a JDK dynamic proxy whose handler is not MapperProxy, or a CGLIB proxy wrapping the mapper.
Common situations: Custom interceptors or MyBatis-Plus internals (e.g. extending the mapper proxy layer) passing the proxy object itself instead of its invocation handler; wrapping mappers in Spring AOP proxies so the reflective layout differs.
Related errors
- Error getting mapper instance. Cause: %s
- Failed to create a new Configuration instance.
- Unable to find a usable constructor for %s
- Unknown execution method for: %s
- Unable to get MybatisMapperProxy : {}
AI-assisted analysis of baomidou/mybatis-plus@bf67d90747 (2026-08-14).
Data as JSON: /api/errors/da747a99971ad3f0.
Report an issue: GitHub.