无法使用jackson和hibernate对Lazy获取的对象进行序列化

时间:2014-12-09 13:43:42

标签: java json hibernate jpa jackson

我们有一个现有的数据库,我们开始使用Java中的hibernate为它创建Entites。 我们正在使用play构建一个Web应用程序!框架,所以我们使用Jackson来序列化和反序列化客户端的对象。 在一个函数中,我们在DB中查询实体列表(例如Report),问题是即使我们明确指定了Eager fetch,一些属性也被Lazy抓取,这导致使用jackson进行序列化问题,因为它不知道如何处理Lazy抓取的对象。

例外:

  

没有找到类org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer的序列化程序,也没有发现创建BeanSerializer的属性(为了避免异常,禁用SerializationConfig.Feature.FAIL_ON_EMPTY_BEANS))(通过引用链:xxxxxxxx)

阐释:

//Our current situation is:
//We have a class report and a class user
Class Reprot{
    [join and fetch eager]
    User user;
}

Class User{
    String firstName;
    String lastName;
}

//And we query a list of Reports:
List<Report> list = typedQuery.getResultList();

//When we try to serialze it:
JsonNode jn = Json.toJson(list);

//it throws the above exception

从我们发现的问题是,hibernate使用缓存(第一级缓存)这样的事实,因此它不必一次又一次地从数据库中获取内容,并且它可能是它所做的,因为每个用户都可以拥有不止一份报告。 所以它的作用是查询列表,当它看到当前报表的用户已经从数据库中获取时,它会放置代理而不是实例,并且该代理被视为无法序列化的Lazy对象

我们搜索了一个解决方案,我们无法找到它,希望这里有人可以帮助我们。

1 个答案:

答案 0 :(得分:0)

您可以通过多种方式处理这种情况。我知道所有解决方案都很艰难且耗时。

  1. 请勿直接将实体发送给客户端。而是创建一个entites的副本(pojo)&gt;将实体值映射到这些新创建的pojos&gt;把它还给客户。有一堆或多个库可以帮助您自动映射类似的对象。在互联网上搜索。

  2. 添加Jackson @Jsonignore注释以忽略您不想要的属性。