MyBatis插件调用SystemMetaObject报错:Class类无'type'属性getter方法
报错原因分析
- 核心问题:你在
interceptotD方法中错误地将实体类的Class对象(soureClass = obj.getClass())传入SystemMetaObject.forObject(),而非实体对象本身。MyBatis的MetaObject是用来操作对象实例的属性的,当传入Class类实例时,它会去寻找Class类本身的type属性的getter方法,而Class类并没有这个属性,因此抛出反射异常。 - 额外问题:
intercepValue方法中的类型判断String.class == metaObject.getGetterType(name)与实体类中type字段的Integer类型不匹配,即使修复前面的错误,也无法完成字段值替换。
解决方案
1. 修正MetaObject的初始化对象
修改interceptotD方法,将SystemMetaObject.forObject(soureClass)替换为传入实体对象obj:
private void interceptotD(Object obj) { if(obj!=null){ Class<?> soureClass = obj.getClass(); // 传入实体对象实例,而非Class对象 MetaObject metaObject = SystemMetaObject.forObject(obj); Stream.of(soureClass.getDeclaredFields()) .filter(field -> field.isAnnotationPresent(DBAC.class)) .forEach(field -> intercepValue(metaObject,field)); } }
2. 修正字段类型判断逻辑
因为实体类中type字段是Integer类型,所以修改intercepValue中的类型判断条件:
private void intercepValue(MetaObject metaObject, Field field) { DBAC annotation = field.getAnnotation(DBAC.class); String name = field.getName(); Object value = metaObject.getValue(name); // 将String.class改为Integer.class,匹配实体类字段类型 if(annotation != null && Integer.class == metaObject.getGetterType(name) && value != null){ metaObject.setValue(name, 0); // 可根据需求替换为合适的占位数值,注意类型匹配 } }
若
@DBAC注解会用到不同数值类型字段上,可改成通用判断:Number.class.isAssignableFrom(metaObject.getGetterType(name))
3. 可选:确保私有字段可访问
虽然@Data已生成getter/setter,MetaObject可正常访问,但遇到特殊字段时,可添加字段可访问配置:
Stream.of(soureClass.getDeclaredFields()) .filter(field -> field.isAnnotationPresent(DBAC.class)) .peek(field -> field.setAccessible(true)) // 确保私有字段可被反射访问 .forEach(field -> intercepValue(metaObject,field));
内容的提问来源于stack exchange,提问作者ShanJu
相关产品推荐
相关产品推荐

