出现这个异常的原因可能是在Controller里面去加载一个懒加载对象,但我们知道,懒加载只能在session打开的状况下才会正常执行,而session在service层就已经关闭了。那怎么解决这个问题呢?
实体类的底层其实就是一个map集合.知道了这个道理,我们就可以把实体类转换成一个map集合去加载.
假如我们要在controller里面去返回一个activiti中的Task对象(它的实现类是一个懒加载对象)
//任务列表
@RequestMapping("/task/list")
@ResponseBody
public List<Task> taskList(){
TaskQuery taskQuery=taskService.createTaskQuery();
List<Task> list=taskQuery.list();
return list;
}
如果我们在前端页面去访问这个路径,就会出现异常:
Could not write content: lazy loading outside command context (through reference chain: java.util.ArrayList[0]->org.activiti.engine.impl.persistence.entity.TaskEntity[“variableInstances”]); nested exception is com.fasterxml.jackson.databind.JsonMappingException: lazy loading outside command context (through reference chain: java.util.ArrayList[0]->org.activiti.engine.
解决:
先给大家分享一个工具类,用来把实体类的指定字段封装成一个map集合
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.HashMap;
import java.util.Map;
import org.springframework.beans.BeanUtils;
public class CommUtil {
/**
* 把指定的复杂对象属性,按照指定的内容,封装到新的map中
* @param source 目标对象
* @param ps 需要封装到map中的属性
* @return
*/
public static Map<String, Object> obj2map(Object source, String[] ps) {
Map<String, Object> map = new HashMap<>();
if (source == null)
return null;
if (ps == null || ps.length < 1) {
return null;
}
for (String p : ps) {
PropertyDescriptor sourcePd = BeanUtils.getPropertyDescriptor(
source.getClass(), p);
if (sourcePd != null && sourcePd.getReadMethod() != null) {
try {
Method readMethod = sourcePd.getReadMethod();
if (!Modifier.isPublic(readMethod.getDeclaringClass()
.getModifiers())) {
readMethod.setAccessible(true);
}
Object value = readMethod.invoke(source, new Object[0]);
map.put(p, value);
} catch (Exception ex) {
throw new RuntimeException(
"Could not copy properties from source to target",
ex);
}
}
}
return map;
}
}
然后我们可以去模拟返回一个List
public List<Map<String, Object>> ProcessDefinationList() {
ProcessDefinitionQuery processDefinitionQuery = repositoryService.createProcessDefinitionQuery();
List<Map<String, Object>> listMap = new ArrayList<>();
// 目标类
List<ProcessDefinition> list = processDefinitionQuery.list();
// 循环
String[] ps = { "id", "name", "version", "key", "diagramResourceName", "resourceName", "deploymentId",
"suspensionState" };
for (ProcessDefinition pd : list) {
Map<String, Object> map = CommUtil.obj2map(pd, ps);
listMap.add(map);
}
return listMap;
}