在hibernate和jackson中反序列化延迟加载

时间:2012-10-16 21:35:24

标签: java hibernate jackson

有没有办法使用id而不是POJO对象来保持LAZY加载和反序列化对象。

我有两个由多对多关系加入的课程。

像这样的东西

public class User {
    @Id
    @JsonProperty
    public long id;

    @ManyToMany(
            fetch = FetchType.EAGER,
    )
    @JoinTable(
            name = "User_EntityType",
            joinColumns = @JoinColumn(name = "user_id"),
            inverseJoinColumns = @JoinColumn(name = "type_id")
    )
    @JsonProperty
    public Set<Type> types;

}

public class Type {
    @Id
    @JsonProperty
    public long id;

    @ManyToMany(
            fetch = FetchType.EAGER,
            mappedBy = "types",
            targetEntity = User.class
    )
    @JsonProperty
    public Set<User> users;
}

数据类型工作得很好。我可以使用hibernate进行编写和读取,没有任何问题。

但是,我希望能够使用REST API返回User对象,因此我使用Jackson对其进行反序列化。问题是,当我这样做时,它反序列化User对象中的每个Type,其中包括其他Type对象,并且它会造成巨大的混乱。

是否可以只返回一组长类型ID而不是类型集?

2 个答案:

答案 0 :(得分:4)

是的,如果您使用的是Jackson 2.0,则可以使用对象标识功能。

如果使用@JsonIdentityInfo注释注释一个类,那么Jackson只会输出一次该对象;后续引用将改为使用ID。因此,只要类型输出一次,您的类型集将被序列化为ID。反序列化杰克逊会将ID转回对象。

在你的情况下,我认为你需要像这样注释你的Type类:

@JsonIdentityInfo(generator=ObjectIdGenerators.PropertyGenerator.class, property="id")
public class Type {
    ...
}

有关如何使用此功能的详细信息,请参阅http://wiki.fasterxml.com/JacksonFeatureObjectIdentity

答案 1 :(得分:0)

我在JAX-RS端点中也面临着这个问题,它必须使用Jackson的对象映射器序列化并提供Hibernate实体。使用@JsonIgnore@JsonIdentityInfo(generator=ObjectIdGenerators.PropertyGenerator.class,...等解决方案的选项对我来说不是一个选项,因为前者意味着关系字段从序列化输出中被省略,而后一种方法排序失败了无论如何解决问题。

所以,我的解决方案是在进行实际序列化之前在mapper上设置以下标志:

ObjectMapper objMapper = new ObjectMapper();
objMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);

这样,没有尝试填充关系对象,而是它们的id保持不变,因此我可以在我的关系字段上保留fetch = FetchType.LAZY标志。