61

杰克逊抛出了一个我不知道如何解决的奇怪异常。我正在使用 Spring、Hibernate 和 Jackson。

我已经考虑过延迟加载会导致问题,但我已采取措施告诉杰克逊不要处理各种属性,如下所示:

@JsonIgnoreProperties({ "sentMessages", "receivedMessages", "educationFacility" })
public class Director extends UserAccount implements EducationFacilityUser {
   ....
}

我对所有其他 UserAccount 子类也做了同样的事情。

这是抛出的异常:

org.codehaus.jackson.map.JsonMappingException: No serializer found for class org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationConfig.Feature.FAIL_ON_EMPTY_BEANS) ) (through reference chain: java.util.ArrayList[46]->jobprep.domain.educationfacility.Director_$$_javassist_2["handler"])
    at org.codehaus.jackson.map.ser.StdSerializerProvider$1.serialize(StdSerializerProvider.java:62)
    at org.codehaus.jackson.map.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:268)
    at org.codehaus.jackson.map.ser.BeanSerializer.serializeFields(BeanSerializer.java:146)
    at org.codehaus.jackson.map.ser.BeanSerializer.serialize(BeanSerializer.java:118)
    at org.codehaus.jackson.map.ser.ContainerSerializers$IndexedListSerializer.serializeContents(ContainerSerializers.java:236)
    at org.codehaus.jackson.map.ser.ContainerSerializers$IndexedListSerializer.serializeContents(ContainerSerializers.java:189)
    at org.codehaus.jackson.map.ser.ContainerSerializers$AsArraySerializer.serialize(ContainerSerializers.java:111)
    at org.codehaus.jackson.map.ser.StdSerializerProvider._serializeValue(StdSerializerProvider.java:296)
    at org.codehaus.jackson.map.ser.StdSerializerProvider.serializeValue(StdSerializerProvider.java:224)
    at org.codehaus.jackson.map.ObjectMapper.writeValue(ObjectMapper.java:925)
    at org.springframework.http.converter.json.MappingJacksonHttpMessageConverter.writeInternal(MappingJacksonHttpMessageConverter.java:153)

关于如何获取更多信息以查看是什么原因的建议?谁知道怎么修它?

编辑:我发现代理对象上存在 getHander() 和其他 get*() 方法。GRR!!有什么办法可以告诉杰克逊不要在代理上处理任何东西,或者我可以吗?这真的很奇怪,因为吐出 JSON 的方法只会在某些情况下崩溃,而不是一直崩溃。尽管如此,这是由于代理对象上的 get*() 方法。

旁白:代理是邪恶的。它们破坏了 Jackson、equals() 和常规 Java 编程的许多其他部分。我很想完全放弃休眠:/

4

15 回答 15

71

通过休眠代理对象进行延迟加载时,我遇到了类似的问题。通过注释具有延迟加载私有属性的类来解决它:

@JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})

我假设您可以在代理对象上添加打破 JSON 序列化到该注释的属性。

避免对未获取的惰性对象进行 Jackson 序列化

于 2011-01-04T07:27:49.077 回答
38

这并不理想,但您可以禁用 Jackson 对 JSON 属性的自动发现,@JsonAutoDetect在类级别使用。这将阻止它尝试处理 Javassist 的东西(并且失败)。

这意味着您必须手动注释每个 getter(使用@JsonProperty),但这不一定是坏事,因为它使事情变得明确。

于 2010-12-06T00:10:59.557 回答
23

我得到了同样的错误,但与休眠无关。我被所有可怕的建议吓到了,我想这与休眠和延迟加载有关......但是,在我的情况下,我得到了错误,因为在内部类中我没有获取器/设置器,所以 BeanSerializer 无法序列化数据...

添加 getter 和 setter 解决了这个问题。

于 2011-11-21T14:26:17.290 回答
9

值得一提的是,Jackson Hibernate 模块项目刚刚开始,它应该可以解决这个问题,希望也能解决其他问题。项目与杰克逊项目有关,但不是核心源代码的一部分。这主要是为了允许更简单的发布过程;它将需要 Jackson 1.7,因为那是引入 Module API 的时候。

于 2010-12-07T17:06:16.473 回答
6

我有同样的问题。看看你是否在使用hibernatesession.load(). 如果是这样,请尝试转换为hibernatesession.get(). 这解决了我的问题。

于 2012-03-29T16:45:49.013 回答
5

我收到了来自 spring 的相同错误消息@RestController。我的休息控制器类正在使用spring的JpaRepository类,并且通过用问题替换repository.getOne(id)方法调用repository.findOne(id)消失了。

于 2014-04-25T06:27:10.647 回答
5

与其他答案类似,对我来说,问题是声明一个多对一列来进行延迟获取。切换到渴望获取解决了这个问题。前:

@ManyToOne(targetEntity = StatusCode.class, fetch = FetchType.LAZY)

后:

@ManyToOne(targetEntity = StatusCode.class, fetch = FetchType.EAGER)
于 2016-10-17T15:24:00.760 回答
4

您可以使用 jackson-datatype-hibernate 模块来解决此问题。它对我有用。参考:https ://github.com/FasterXML/jackson-datatype-hibernate

于 2014-02-10T02:26:39.110 回答
2

@JsonIgnoreProperties(value = { "handler", "hibernateLazyInitializer" })你可以在你的班级“导演”上使用注释

于 2012-07-20T08:50:06.413 回答
2

您可以在 Object.class 上添加 Jackson mixin 以始终忽略与休眠相关的属性。如果您使用的是 Spring Boot,请将其放在您的 Application 类中:

@Bean
public Jackson2ObjectMapperBuilder jacksonBuilder() {
    Jackson2ObjectMapperBuilder b = new Jackson2ObjectMapperBuilder();
    b.mixIn(Object.class, IgnoreHibernatePropertiesInJackson.class);
    return b;
}


@JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})
private abstract class IgnoreHibernatePropertiesInJackson{ }
于 2017-05-24T07:15:59.907 回答
0

我是 Jackson API 的新手,当我收到 "org.codehaus.jackson.map.JsonMappingException: No serializer found for class com.company.project.yourclass" 时,我将 getter 和 setter 添加到 com.company.project.yourclass ,这有助于我使用 ObjectMapper 的映射器对象将 java 对象写入平面文件。

于 2012-06-08T09:52:57.967 回答
0

我遇到了同样的问题,同样的代码在少数情况下有效,而在某些随机情况下却失败了,这真的很奇怪。

我通过确保正确的 setter/getter 来解决它(确保区分大小写)

于 2013-11-06T07:14:34.680 回答
0

我试过@JsonDetect

@JsonIgnoreProperties(value = { "handler", "hibernateLazyInitializer" })

他们都不为我工作。使用第三方模块对我来说似乎是很多工作。所以我只是尝试get在传递给序列化之前调用惰性对象的任何属性jackson。工作代码片段看起来像这样:

@RequestMapping(value = "/authenticate", produces = "application/json; charset=utf-8")
    @ResponseBody
    @Transactional
    public Account authenticate(Principal principal) {
        UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = (UsernamePasswordAuthenticationToken) principal;
        LoggedInUserDetails loggedInUserDetails = (LoggedInUserDetails) usernamePasswordAuthenticationToken.getPrincipal();
        User user = userRepository.findOne(loggedInUserDetails.getUserId());
        Account account = user.getAccount();
        account.getFullName();      //Since, account is lazy giving it directly to jackson for serlization didn't worked & hence, this quick-fix.
        return account;
    }
于 2015-03-12T20:36:02.717 回答
0

您也可以使您的域对象 Director 成为最终的。这不是完美的解决方案,但它会阻止创建域类的代理子类。

于 2016-09-15T21:16:31.793 回答