我通过MappingJacksonHttpMessageConverter使用带有Hibernate / Spring MVC的jackson 1.9.2。
杰克逊无法序列化双向一对多关系并进行无限循环。
我正在使用的课程是:
包含一组SMS实例的对话。
每个SMS实例都有一组PhoneNumbers
每个PhoneNumber都有一个父联系人(这是双向的多对一关系)
我要做的是序列化对话。
如果我不使用 @JsonManagedReference 和 @JsonBackReference ,那么jackson会因无限循环而崩溃。但是当我使用它们时, 联系 不会序列化为 PhoneNumber 。
Class Contact { @JsonManagedReference List<PhoneNumber> phoneNumber ; } Class PhoneNumber { @JsonBackReference Contact contact; }
输出结果为:
{ <--------------------- Conversation "id": 51, "smsSet": [ { "id": 53, "origin": 0123465, "destination": "06533844XY", "message": "Hello world!", "phoneNumbers": [ { "id": 64, "num": "06533844XY", "creationDate": 1333992533000, } ], } ], "creationDate": 1333992534000 }
而不是
{ <---------- conversation "id": 51, "smsSet": [ { "id": 53, "origin": 0123465, "destination": "06533844XY", "message": "Hello world!", "phoneNumbers": [ { "id": 64, "num": "06533844XY", "creationDate": 1333992533000, "contact": <--------------------- Missing part { "id": 12, "name": "Samuel Jackson", "primaryNumber": "06533844XY" } } ], } ], "creationDate": 1333992534000 }
答案 0 :(得分:7)
我最近遇到了类似的问题:杰克逊 - 具有双向关系的实体的序列化(避免循环)
因此,解决方案是升级到Jackson 2.0,并向类中添加以下注释:
@JsonIdentityInfo(generator = ObjectIdGenerators.IntSequenceGenerator.class,
property = "@id")
public class SomeEntityClass ...
然后问题是Spring不能与Jackson 2.0一起使用。这已通过以下方式解决:
<bean id="jacksonMessageConverter"
class="own.implementation.of.MappingJacksonHttpMessageConverter"/>
<bean class="org.springframework.web.servlet.mvc
.annotation.AnnotationMethodHandlerAdapter">
<property name="messageConverters">
<list>
<ref bean="jacksonMessageConverter"/>
</list>
</property>
<property name="requireSession" value="false"/>
</bean>
self.implementation.of.MappingJacksonHttpMessageConverter基于此:
但是使用杰克逊2.0中的ObjectMapper
和其他Jackson课程而不是Jackson 1。*
答案 1 :(得分:1)
作为第一个解决方案,我保留了这些注释并创建了另一个类:ContactWithouPhoneNumber并将其作为字段添加到PhoneNumber类中。
现在,在渲染之前,我会复制除PhoneNumber之外的所有字段,从联系人到contactWithoutPhoneNumber。输出JSON包含我需要的所有东西。
这是DTO设计模式。
答案 2 :(得分:0)
你的班级def有一件事是使用无类型的List
;你应该宁愿:
List<PhoneNumber> phoneNumber ;
因为杰克逊不知道反序列化时的类型是什么;甚至在序列化时它可能会导致问题(因为基本类型不确定)。 所以我先解决这个问题。
但另外你的依赖可能是错误的方式:@JsonManagedReference
必须始终是序列化的第一件事。如果不是这种情况,则无法使用这些注释。
如果没有看到您尝试序列化的对象,很难确定(POJO定义和JSON似乎略微偏离)。
答案 3 :(得分:0)
您可以将@JsonIgnore添加到字段中,映射器将在序列化期间跳过它们。它的功能类似于@Transient。
它位于jackson-core-asl。