Hibernate懒加载导致json数据对象传输异常的问题---(非常重要)
2016-12-15 20:30
761 查看
1. 异常:
[console_demo][WARN] [2016-12-15 19:49:35] org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver.handleHttpMessageNotWritable(407) | Failed to write HTTP message: org.springframework.http.converter.HttpMessageNotWritableException: Could
not write content: No serializer found for class org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS) (through reference chain:
java.util.HashMap["ckRequirePartLists"]->java.util.ArrayList[0]->com.dyoon.cmms.pojo.CkRequirePartList["ckPurchaseBill"]->com.dyoon.cmms.pojo.CkPurchaseBill["applyOperator"]->com.dyoon.cmms.pojo.UserOperator_$$_jvsta2a_12["sysRole"]->com.dyoon.cmms.pojo.SysRole_$$_jvsta2a_8["userModifyLog"]->com.dyoon.cmms.pojo.UserModifyLog_$$_jvsta2a_6["handler"]);
nested exception is com.fasterxml.jackson.databind.JsonMappingException: No serializer found for class org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS)
(through reference chain: java.util.HashMap["ckRequirePartLists"]->java.util.ArrayList[0]->com.dyoon.cmms.pojo.CkRequirePartList["ckPurchaseBill"]->com.dyoon.cmms.pojo.CkPurchaseBill["applyOperator"]->com.dyoon.cmms.pojo.UserOperator_$$_jvsta2a_12["sysRole"]->com.dyoon.cmms.pojo.SysRole_$$_jvsta2a_8["userModifyLog"]->com.dyoon.cmms.pojo.UserModifyLog_$$_jvsta2a_6["handler"])
2. 原因:
使用注解@ResponseBody返回由Hibernate DAO直接获得的pojo对象内存在Lazy关联对象,执行Jason转换时,会从数据库加载该对象,而此时session已关闭,导致加载失败,进而导致Jason转换失败。
3 解决:
方法一:在不影响数据完整性的情况下,使用set方法手动置空pojo类的Lazy关联对象。(这样如果关联的对象比较多,可能漏的。)
方法二:使用@JsonIgnore注释掉pojo类的Lazy关联对象。(这种如果在其他的地方需要用关联的对象转json,这样就会导致失效。)
方法三:自定义类,二次封装所需的pojo对象的属性。
4. 事例:以下对第三种方法做展示
jsp页面:
function showPartDetails(purchBillId){
$.ajax({
type:"post",
url:"${rootPath }/depot/purchase/getPartByPurchBillId?purchBillId="+purchBillId,
success : function(data){ alert(data.requirePartListBeans[0].partName); }
});
}通过ajax发送请求到controller,服务器处理结果,将结果以json的格式发送给前端。
常规下的controller如下:
@RequestMapping(value = "/getPartByPurchBillId")
@ResponseBody
public Map<String,Object> getPartByPurchBillId(@RequestParam(value="purchBillId") Integer purchBillId) throws JsonProcessingException {
Map<String, Object> map = new HashMap<>();
List<CkRequirePartList> ckRequirePartLists = purchaseService.getPartByPurchBillId(purchBillId);
map.put("requirePartListBeans", ckRequirePartLists);
return map;
}但是由于hibernate懒加载的问题,requirePartListBeans不能正常的转换为json,这时候将前端要获取的属性数据封装成一个类,以下为假如前端要获取的3条数据:
public class RequirePartListBean {
private String partNumber;
private String partName;
private BigDecimal partQuantity;
public String getPartNumber() {
return partNumber;
}
public void setPartNumber(String partNumber) {
this.partNumber = partNumber;
}
public String getPartName() {
return partName;
}
public void setPartName(String partName) {
this.partName = partName;
}
public BigDecimal getPartQuantity() {
return partQuantity;
}
public void setPartQuantity(BigDecimal partQuantity) {
this.partQuantity = partQuantity;
}
}更改后的controller为:
@RequestMapping(value = "/getPartByPurchBillId")
@ResponseBody
public Map<String,Object> getPartByPurchBillId(@RequestParam(value="purchBillId") Integer purchBillId) throws JsonProcessingException {
Map<String, Object> map = new HashMap<>();
List<CkRequirePartList> ckRequirePartLists = purchaseService.getPartByPurchBillId(purchBillId);
RequirePartListBean r = null;
List<RequirePartListBean> requirePartListBeans = new ArrayList<>();
for (CkRequirePartList ckRequirePartList : ckRequirePartLists) {
r = new RequirePartListBean();
r.setPartName(ckRequirePartList.getModPartCatalog().getPartName());
r.setPartNumber(ckRequirePartList.getModPartCatalog().getPartNumber());
r.setPartQuantity(ckRequirePartList.getPartQuantity());
requirePartListBeans.add(r);
}
map.put("requirePartListBeans", requirePartListBeans);
return map;
}前端ajax通过success响应数据,
至此,问题得到解决。还有问题的可以留言。
[console_demo][WARN] [2016-12-15 19:49:35] org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver.handleHttpMessageNotWritable(407) | Failed to write HTTP message: org.springframework.http.converter.HttpMessageNotWritableException: Could
not write content: No serializer found for class org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS) (through reference chain:
java.util.HashMap["ckRequirePartLists"]->java.util.ArrayList[0]->com.dyoon.cmms.pojo.CkRequirePartList["ckPurchaseBill"]->com.dyoon.cmms.pojo.CkPurchaseBill["applyOperator"]->com.dyoon.cmms.pojo.UserOperator_$$_jvsta2a_12["sysRole"]->com.dyoon.cmms.pojo.SysRole_$$_jvsta2a_8["userModifyLog"]->com.dyoon.cmms.pojo.UserModifyLog_$$_jvsta2a_6["handler"]);
nested exception is com.fasterxml.jackson.databind.JsonMappingException: No serializer found for class org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS)
(through reference chain: java.util.HashMap["ckRequirePartLists"]->java.util.ArrayList[0]->com.dyoon.cmms.pojo.CkRequirePartList["ckPurchaseBill"]->com.dyoon.cmms.pojo.CkPurchaseBill["applyOperator"]->com.dyoon.cmms.pojo.UserOperator_$$_jvsta2a_12["sysRole"]->com.dyoon.cmms.pojo.SysRole_$$_jvsta2a_8["userModifyLog"]->com.dyoon.cmms.pojo.UserModifyLog_$$_jvsta2a_6["handler"])
2. 原因:
使用注解@ResponseBody返回由Hibernate DAO直接获得的pojo对象内存在Lazy关联对象,执行Jason转换时,会从数据库加载该对象,而此时session已关闭,导致加载失败,进而导致Jason转换失败。
3 解决:
方法一:在不影响数据完整性的情况下,使用set方法手动置空pojo类的Lazy关联对象。(这样如果关联的对象比较多,可能漏的。)
方法二:使用@JsonIgnore注释掉pojo类的Lazy关联对象。(这种如果在其他的地方需要用关联的对象转json,这样就会导致失效。)
方法三:自定义类,二次封装所需的pojo对象的属性。
4. 事例:以下对第三种方法做展示
jsp页面:
function showPartDetails(purchBillId){
$.ajax({
type:"post",
url:"${rootPath }/depot/purchase/getPartByPurchBillId?purchBillId="+purchBillId,
success : function(data){ alert(data.requirePartListBeans[0].partName); }
});
}通过ajax发送请求到controller,服务器处理结果,将结果以json的格式发送给前端。
常规下的controller如下:
@RequestMapping(value = "/getPartByPurchBillId")
@ResponseBody
public Map<String,Object> getPartByPurchBillId(@RequestParam(value="purchBillId") Integer purchBillId) throws JsonProcessingException {
Map<String, Object> map = new HashMap<>();
List<CkRequirePartList> ckRequirePartLists = purchaseService.getPartByPurchBillId(purchBillId);
map.put("requirePartListBeans", ckRequirePartLists);
return map;
}但是由于hibernate懒加载的问题,requirePartListBeans不能正常的转换为json,这时候将前端要获取的属性数据封装成一个类,以下为假如前端要获取的3条数据:
public class RequirePartListBean {
private String partNumber;
private String partName;
private BigDecimal partQuantity;
public String getPartNumber() {
return partNumber;
}
public void setPartNumber(String partNumber) {
this.partNumber = partNumber;
}
public String getPartName() {
return partName;
}
public void setPartName(String partName) {
this.partName = partName;
}
public BigDecimal getPartQuantity() {
return partQuantity;
}
public void setPartQuantity(BigDecimal partQuantity) {
this.partQuantity = partQuantity;
}
}更改后的controller为:
@RequestMapping(value = "/getPartByPurchBillId")
@ResponseBody
public Map<String,Object> getPartByPurchBillId(@RequestParam(value="purchBillId") Integer purchBillId) throws JsonProcessingException {
Map<String, Object> map = new HashMap<>();
List<CkRequirePartList> ckRequirePartLists = purchaseService.getPartByPurchBillId(purchBillId);
RequirePartListBean r = null;
List<RequirePartListBean> requirePartListBeans = new ArrayList<>();
for (CkRequirePartList ckRequirePartList : ckRequirePartLists) {
r = new RequirePartListBean();
r.setPartName(ckRequirePartList.getModPartCatalog().getPartName());
r.setPartNumber(ckRequirePartList.getModPartCatalog().getPartNumber());
r.setPartQuantity(ckRequirePartList.getPartQuantity());
requirePartListBeans.add(r);
}
map.put("requirePartListBeans", requirePartListBeans);
return map;
}前端ajax通过success响应数据,
success : function(data){ alert(data.requirePartListBeans[0].partName); }
至此,问题得到解决。还有问题的可以留言。
相关文章推荐
- hibernate+spring mvc, 解决hibernate 对象懒加载 json序列化问题
- dubbo使用POJO对象传输数据的RemotingException异常问题
- Hibernate懒加载问题导致View层无法获取关联数据的问题
- Spring MVC返回hibernate对象序列化json报懒加载出错的问题
- hibernate懒加载导致对象json化失败问题解决
- json解决hibernate中级联对象延迟加载有关问题
- Apache页面压缩配置问题导致json数据传输时间延长
- Hibernate 延迟加载导致的问题 net.sf.json.JSONException: There is a cycle in the hierarchy!
- fastjson序列化hibernate代理和延迟加载对象出现no session异常的解决办法
- fastjson序列化hibernate代理和延迟加载对象出现no session异常的解决办法
- json解决hibernate中级联对象延迟加载问题net.sf.json.JSONException: org....
- Apache页面压缩配置问题导致json数据传输时间延长
- json解决hibernate中级联对象延迟加载问题net.sf.json.JSONException: org....
- 关于使用json数据传递的时候hibernate的懒加载问题
- struts2 json插件返回hibernate延迟加载对象过多卡死问题
- fastjson序列化hibernate代理和延迟加载对象出现no session异常的解决办法
- Apache页面压缩配置问题导致json数据传输时间延长
- jackson json数据过滤,用于hibernate的懒加载对象级联关系的json解析
- Ext中TreeLoader加载json数据文件问题
- extjs JsonStore加载数据,Combobox只显示最后一项值问题