关于Jackson反序列化Mybatis ResultMap类找不到的问题
分类:Java 浏览:55 时间:2020-05-19 09:59

近期在使用redis对数据进行缓存,通过Jackson将对象转换成字符串并保留类信息(@class),使用Jedis自定义实现Spring缓存逻辑。开发过程中发现,每当应用重启就会报:Could not resolve type id _$$_jvst as a subtype of `java.lang.Object`: no such class found。类没有找到。

<resultMap type="com.xxxxx.Abc"
           id="sabcResultMap">
    <result property="id" column="id"/>
    <result property="code" column="code"/>
    <result property="type" column="type"/>
    <result property="fieldName" column="field_name"/>
    <result property="sort" column="sort"/>
    <result property="placeholder" column="placeholder"/>
    <result property="required" column="required"/>
    <collection property="abcConstraintList"
                javaType="java.util.ArrayList"
                column="id"
                ofType="com.xxxxx.AbcConstraint"
                select="com.xxxxx.AbcConstraintDAO.listByAbcId"/>
</resultMap>


上面这段是mybatis的resultMap配置,查询的是一个resultMap,按照以往的思路和理解resultMap会映射成com.xxxx.Abc这个类的实例。


但查询结果其实是一个代理类,mybaits的命名规则为com.xxxx.Abc_$$_jvst12类似这样命名的类,而且每次重启应用后,下一次查询又是另一个名称的类。

{"@class":"com.xxxx.Abc_$$_jvst12","id":1001,"code":"test","type":"checkbox"}

所以如果查询结果先转换成JSON再缓存到redis中,然后在重启应用后,再次查询时先从缓存中获取出来的类信息@class是找不到的,并会抛出no such class found的异常。


如何解决此问题?在几经波折google无果后,我决定跟代码进行调试,发现这个动态生成的类是在org.apache.ibatis.executor.resultset.DefaultResultSetHandler的596行处理的,延迟加载导致的。


此时我回想hibernate的entity都是代理对象,都过代理实现延迟加载,恍然大悟。


直接修改mybatis配置文件,将lazyLoadingEnabled设置为false。

<setting name="lazyLoadingEnabled" value="false"/>

如果你想保留延迟加载,那这个方法不可行,或许你需要自定义Jackson的序列化逻辑,或者改变spring cache的缓存逻辑。


经测试,问题完美解决!

蛋疼集锦