JFinal renderJson 异常

public void getEntityTypes() {

List<TagEntityType> json = tagEntityTypeService.getEntityTypes();

renderJson(json);

}

单步跟踪json的值如下,

[com.ai.ctos.bdi.module.tagentitytype.TagEntityType@8aa3b4cd {id:1, edit_at:null, create_at:2016-07-12 09:22:29.0, type_name:信用, remarks:信用产品类}]


然后执行renderJson(json);的时候,控制台显示查询语句n次:

Sql: select * from tag_entity_type order by id limit 10


然后,一直抛异常:

at com.fasterxml.jackson.databind.ser.impl.IndexedListSerializer.serializeContents(IndexedListSerializer.java:119)

at com.fasterxml.jackson.databind.ser.impl.IndexedListSerializer.serialize(IndexedListSerializer.java:79)

at com.fasterxml.jackson.databind.ser.impl.IndexedListSerializer.serialize(IndexedListSerializer.java:18)

at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:672)

at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:678)

at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:157)

at com.fasterxml.jackson.databind.ser.impl.IndexedListSerializer.serializeContents(IndexedListSerializer.java:119)

at com.fasterxml.jackson.databind.ser.impl.IndexedListSerializer.serialize(IndexedListSerializer.java:79)

at com.fasterxml.jackson.databind.ser.impl.IndexedListSerializer.serialize(IndexedListSerializer.java:18)

at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:672)

at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:678)

at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:157)

at com.fasterxml.jackson.databind.ser.impl.IndexedListSerializer.serializeContents(IndexedListSerializer.java:119)

at com.fasterxml.jackson.databind.ser.impl.IndexedListSerializer.serialize(IndexedListSerializer.java:79)

at com.fasterxml.jackson.databind.ser.impl.IndexedListSerializer.serialize(IndexedListSerializer.java:18)

at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:672)

at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:678)

at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:157)

at com.fasterxml.jackson.databind.ser.impl.IndexedListSerializer.serializeContents(IndexedListSerializer.java:119)

at com.fasterxml.jackson.databind.ser.impl.IndexedListSerializer.serialize(IndexedListSerializer.java:79)

Caused by: java.lang.StackOverflowError

at java.lang.ClassLoader.defineClass1(Native Method)

at java.lang.ClassLoader.defineClass(ClassLoader.java:800)

at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)

at java.net.URLClassLoader.defineClass(URLClassLoader.java:449)

at java.net.URLClassLoader.access$100(URLClassLoader.java:71)

at java.net.URLClassLoader$1.run(URLClassLoader.java:361)

at java.net.URLClassLoader$1.run(URLClassLoader.java:355)

at java.security.AccessController.doPrivileged(Native Method)

at java.net.URLClassLoader.findClass(URLClassLoader.java:354)

at java.lang.ClassLoader.loadClass(ClassLoader.java:425)

at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)

at java.lang.ClassLoader.loadClass(ClassLoader.java:358)

at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:697)

... 1011 more


请教下@JFinal是什么引起的错误,这是第二次遇到。


跟踪异常抛出位置:

com.fasterxml.jackson.databind.ObjectMapper的2980行:

 _configAndWriteValue(_jsonFactory.createGenerator(sw), value);

当前的value值为:

[com.ai.ctos.bdi.module.tagentitytype.TagEntityType@8aa3b4cd {id:1, edit_at:null, create_at:2016-07-12 09:22:29.0, type_name:信用, remarks:信用产品类}]

评论区

JFinal

2016-07-12 10:23

应该是被转换的对象之中出现了循环依赖,转换的时候造成死循环,jackson 貌似无法处理循环依赖。换成 JFinalJson 或者 fastjson 试一下

小飞象

2016-07-12 10:29

@JFinal 刚试了fastjson同样报异常,JFinalJson getter 好像有问题,比如typeName显示不了。

小飞象

2016-07-12 10:31

@JFinal 按道理 Sql: select * from tag_entity_type order by id limit 10 就是个单表查询啊 不存在循环依赖,并且数据表就一条记录。

JFinal

2016-07-12 10:59

@小飞象 在对 TagEntityType 对象进行json 转换时,调用了其中的 getter 方法获取数据,而 getter 方法又去读了数据库,将读取出来的数据再进行 json 转换,如果数据表中的 TagEntityType 记录之间存在依赖关系,例如用了 pid 之类的字段表示了记录之间的关系,一旦出现循环依赖,那么转换必然就会出现死循环,这种循环依赖发生在数据表,而不是内存的对象中,本质上是一样的。单步调试一下就清楚了

JFinal

2016-07-12 11:02

@小飞象 简单来说就是:转换时调用了 getter,调用 getter 时查询了数据库,再进行转换,转换时又调用了 getter,如果数据表中的数据是循环依赖的,转换将陷入死循环。 如果这种循环依赖是在内存中,fastjson 是可以探测到的,但在数据库中发生时并没有处理