我正在使用Hibernate 4.1和Spring 3.1。
考虑以下User类引用其他对象,包括self。我定义的所有hibernate映射都是LAZY,所以只有当我在jsp或其他代码中使用它们时才会加载引用对象。
class User {
private User createdBy;
private Department department;
private Project project;
.....
.....
}
问题是当我想要返回一个JSON表示时,它使用反射来执行它,然后执行深度序列化。下面是我的控制器代码。
@ResponseBody
public User getUser(int id) {
User user = [fetch user from service];
return user;
}
由于我有自引用,它也会进入无限循环。
解决这个问题的解决方案是什么?我知道我需要使用DTO模式,而不是返回UserDTO,而是我创建了多少这样的方法。例如,在一个地方我只需要基本的用户属性,在其他地方我需要用户及其部门,在其他地方我需要用户部门和项目。
我需要暴露多少这样的方法。有没有其他方法可以解决这个问题?
答案 0 :(得分:1)
问题是你有一个循环引用,你的JSON编码器没有处理它。所以,你需要手动处理它。
如您所评论的那样创建DTO会有所帮助。您可以使用一种方法为您需要的每个级别的解码实现一个Helper。
您可以使用BeanUtils
将每个属性从一个bean复制到另一个bean。
另一个解决方案(更具概念性)将是:
为每个边界方法实现一种装饰器,并在结果上应用dozer。您可以采用here
的示例装饰或多或少地出现:
public interface Controller {
User getUser(int id);
}
public class RealController {
public User getUser(int id) {
return dao.getUser(id);
}
}
public class DecoratedController {
private Controller realController;
public User getUser(int id) {
// here you will apply dozer or do it manually creating an object with so deep as you wish
return flatUserStructure(realController.getUser(id));
}
}
答案 1 :(得分:0)
为了能够调整Hibernate关联加载,您可以使用获取加入,请阅读14.3. Associations and joins
为了避免深度序列化问题,您可以创建适当的DTO并使用@JsonIgnore项目的Jackson Java JSON-processor注释等内容进行调整。
答案 2 :(得分:0)