80337960 2018-07-05
最近在使用JPA的时候发现了,有lombok存在的时候,使用JPA查询出来的嵌套对象无法正确转换成JSON。
我们先来复现这个问题:
1.
非常简单的entity,用过hibernate的都懂,里面的嵌套1对多对象是Code。
可以看到
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode(callSuper=false)
@Data
这四个对象来自lombok,分表代表的内容为:无参构造器,全参构造器,重写equals和hashcode方法及所有参数的set get方法。
这是嵌套对象Code的代码。
2.有了这个entity,然后我们正常存入某些对象,then,进行最基本的查询操作。
3.就会出现如下异常。
显然,已经栈溢出了。
也显然,是因为在对象转Json的时候已经递归进行导致栈溢出。
4.思考
细心的朋友应该已经发现了,我在entity中加入了JsonView 来控制json转换,那为什么还是会出现这种com.fasterxml.jackson.databind.JsonMappingException 呢?
逻辑是没有问题的(熟悉jsonview的就知道),只可能出现在某些工具错误上。
于是我想到了lombok,在本项目中新引用的东西,动态的生成代码(还未深入研究其原理)
经过多次的变量控制法,最后确定只有在1对多实体上(e.g. Group) 使用了@Data 或 @EqualsAndHashCode 就会出现这个问题。
所以解决办法:去掉@EqualsAndHashCode 及 @Data ,全部改为手写(其实就是让idea帮你生成,有真正的代码)
最终的思考结果:对象转换使用的是spring自己的fastjson,而lombok是动态生成的代码,其中lombok改写了equals及hashcode方法可能倒是fastjson在对比两个对象时候产生了错误,这是其一。第二使用@data生成get,set方法的时候,影响了jpa查询出来对象封装进入普通对象。