【问题标题】:Can't serialize Lazy fetched objects using jackson and hibernate无法使用杰克逊和休眠序列化延迟获取的对象
【发布时间】:2015-02-07 10:18:51
【问题描述】:

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

例外:

没有找到类 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 使用缓存(一级缓存),因此它不必一次又一次地从数据库中获取内容,这可能是因为每个用户都可以拥有多于一份报告。 所以它所做的是查询列表,当它看到当前报告的用户已经从数据库中获取时,它会放置一个代理而不是实例,并且该代理被视为无法序列化的惰性对象.

我们搜索了一个解决方案,但我们找不到它,希望这里的任何人都可以帮助我们。

【问题讨论】:

  • 试试 jackson hibernate 模块。 github.com/FasterXML/jackson-datatype-hibernate
  • 你可能认为你有你的对象的实例,但你有的是 java.reflect.Proxy 实例,这些实例不容易被序列化。这是让我摆脱冬眠的面部表情之一。很有趣,你用杰克逊标记了这个问题。我的项目中也有杰克逊用于外部 Web 界面。我意识到,我已经有一种序列化对象(JSON)的方法,我不需要另一种(sql 数据库)。所以我只是切换到 Mongo 并使用我的 Jackson 序列化器进行持久性序列化。我不知道我扔掉了多少万行代码。
  • 检查这是否有助于stackoverflow.com/a/24994562/3447216

标签: java json hibernate jpa jackson


【解决方案1】:

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

  1. 不要将实体直接发送给客户端。而是创建实体的副本(pojo)> 将实体值映射到这些新创建的 pojo > 将其返回给客户端。有一堆或库可以帮助您自动映射类似的对象。在互联网上搜索。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-05-25
    • 2013-07-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多