在jpa和hibernate的一对多和多对多查询的时候,常常会出现死循环的情况。
出现这种情况主要是在json序列化的时候,出现循环引用的情况,与后台查询的语句无关。所以只要在json序列化的时候,进行处理就可以了。
本文使用json工具进行处理序列化问题:
package bos.utils;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import net.sf.json.JsonConfig;
import java.util.List;
public class JsonUtils {
//strings序列化出现循环引用的字段
public static String objecttojson(Object object,String[] strings) {
JsonConfig jsonConfig=new JsonConfig();
jsonConfig.setExcludes(strings);
JSONObject fromObject = JSONObject.fromObject(object, jsonConfig);
String json=fromObject.toString();
return json;
}
public static String arraytojson(List list,String[] strings ){
JsonConfig jsonConfig=new JsonConfig();
jsonConfig.setExcludes(strings);
JSONArray fromObject = JSONArray.fromObject(list,jsonConfig);
String json=fromObject.toString();
return json;
}
}
处理之前的处理代码和结果
@RequestMapping("/list")
@ResponseBody
public PageBean list(int page, int rows){
Pageable pageable= PageRequest.of(page-1,rows);
Page<Function> rolePage = functionService.findAll(pageable);
PageBean pageBean=new PageBean();
pageBean.setCurrentPage(page);
pageBean.setPageSize(rows);
pageBean.setTotal((int) functionService.count());
pageBean.setRows(rolePage.getContent());
//防止出现死循环
// String objecttojson = JsonUtils.objecttojson(pageBean, new String[]{"roles","parentFunction","children"});
// return objecttojson;
return pageBean;
}
出现错误:
修改后代码:
@RequestMapping("/list")
@ResponseBody
public String list(int page, int rows){
Pageable pageable= PageRequest.of(page-1,rows);
Page<Function> rolePage = functionService.findAll(pageable);
PageBean pageBean=new PageBean();
pageBean.setCurrentPage(page);
pageBean.setPageSize(rows);
pageBean.setTotal((int) functionService.count());
pageBean.setRows(rolePage.getContent());
//防止出现死循环
String objecttojson = JsonUtils.objecttojson(pageBean, new String[]{"roles","parentFunction","children"});
return objecttojson;
// return pageBean;
}
处理结果:
总结:对于多对对和一对多的双方关联,会出现循环引用的情况。解决方法基本如下
- 将双方关联改成一方关联也能解决死循环的问题,但是这种方法不太推荐
- 采用本文的方法,在序列化之前剔除循环引用的字段
- 使用@JsonIgnoreProperties注解进行解决,本人尝试过好像不太行,如果有小伙伴会的话,可以联系我。