添加Interceptor后出现com.sun.proxy.$Proxy398无delegate getter错误求助
MyBatis拦截器获取MappedStatement报错解决
报错信息:
There is no getter for property named 'delegate' in 'class com.sun.proxy.$Proxy398'
错误触发代码行:
MappedStatement mappedStatement = (MappedStatement) metaObject.getValue("delegate.mappedStatement");
问题原因
拦截到的StatementHandler是JDK动态代理对象,而非MyBatis原生的RoutingStatementHandler实例,代理类本身没有delegate属性的getter方法,直接通过metaObject.getValue("delegate.mappedStatement")会触发属性找不到的异常。
解决方法
方案1:剥离代理获取真实对象
循环判断并获取真实的StatementHandler实例,再通过MetaObject访问内部属性:
StatementHandler statementHandler = (StatementHandler) invocation.getTarget(); // 逐层剥离代理,拿到真实的MyBatis实现类 while (Proxy.isProxyClass(statementHandler.getClass())) { statementHandler = (StatementHandler) Proxy.getInvocationHandler(statementHandler) .invoke(statementHandler, new Method[]{}, new Object[]{}); } MetaObject metaObject = SystemMetaObject.forObject(statementHandler); MappedStatement mappedStatement = (MappedStatement) metaObject.getValue("delegate.mappedStatement");
方案2:异常兼容处理
先尝试访问delegate.mappedStatement,失败则直接获取mappedStatement(部分场景下代理对象可能直接持有该属性):
MetaObject metaObject = SystemMetaObject.forObject(invocation.getTarget()); MappedStatement mappedStatement; try { mappedStatement = (MappedStatement) metaObject.getValue("delegate.mappedStatement"); } catch (Exception e) { mappedStatement = (MappedStatement) metaObject.getValue("mappedStatement"); }
补充说明
MyBatis插件机制会对目标对象生成动态代理,不同版本或配置下代理层数可能不同,处理时需确保拿到真实的MyBatis实现类实例,再操作其内部属性。
内容的提问来源于stack exchange,提问作者Forest10
相关产品推荐
相关产品推荐

