Hibernate使用2个指向同一对象的外键导致序列化问题

时间:2015-11-22 14:21:35

标签: java json hibernate

我有一个类Post,它有两个字段,它们是Post对象的外键。一切正常,而我只使用其中一个,当我添加另一个时,它导致奇怪的infinite loop看起来像JSON。

我的实体类:

@Entity
@Table(name = "Posts", catalog = "StackOverflow")

public class Post {
    private Integer Id, PostTypeId, ParentId, AcceptedAnswerId, Score, ViewCount, OwnerUserId, LastEditorUserId, AnswerCount,
            CommentCount, FavoriteCount;
    private String Body, Title, Tags;
    private Date CreationDate, LastEditDate, LastActivityDate;
    private Post parentPost;
    private Post acceptedAnswer;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "Id", unique = true, nullable = false)
    public Integer getId() {
        return Id;
    }

    public void setId(Integer id) {
        Id = id;
    }

    @Column(name = "PostTypeId")
    public Integer getPostTypeId() {
        return PostTypeId;
    }

    public void setPostTypeId(Integer postTypeId) {
        PostTypeId = postTypeId;
    }

    @ManyToOne(cascade = CascadeType.ALL)
    @JoinColumn(name = "ParentId", referencedColumnName = "Id")
    public Post getParentPost(){
        return parentPost;
    }

    public void setParentPost(Post parentPost) {
        this.parentPost = parentPost;
    }
    /*@Column(name = "ParentId")
    public Integer getParentId() {
        return ParentId;
    }

    public void setParentId(Integer parentId) {
        ParentId = parentId;
    }*/



    @OneToOne(cascade = CascadeType.ALL)
    @JoinColumn(name = "AcceptedAnswerId", referencedColumnName = "Id")
    public Post getAcceptedAnswer(){
        return acceptedAnswer;
    }

    public void setAcceptedAnswer(Post acceptedAnswer) {
        this.acceptedAnswer = acceptedAnswer;
    }
    /*@Column(name = "AcceptedAnswerId")
    public Integer getAcceptedAnswerId() {
        return AcceptedAnswerId;
    }

    public void setAcceptedAnswerId(Integer acceptedAnswerId) {
        AcceptedAnswerId = acceptedAnswerId;
    }*/

    @Column(name = "Score")
    public Integer getScore() {
        return Score;
    }

    public void setScore(Integer score) {
        Score = score;
    }
    @Column(name = "ViewCount")
    public Integer getViewCount() {
        return ViewCount;
    }

    public void setViewCount(Integer viewCount) {
        ViewCount = viewCount;
    }
    @Column(name = "OwnerUserId")
    public Integer getOwnerUserId() {
        return OwnerUserId;
    }

    public void setOwnerUserId(Integer ownerUserId) {
        OwnerUserId = ownerUserId;
    }
    @Column(name = "LastEditorUserId")
    public Integer getLastEditorUserId() {
        return LastEditorUserId;
    }

    public void setLastEditorUserId(Integer lastEditorUserId) {
        LastEditorUserId = lastEditorUserId;
    }
    @Column(name = "AnswerCount")
    public Integer getAnswerCount() {
        return AnswerCount;
    }

    public void setAnswerCount(Integer answerCount) {
        AnswerCount = answerCount;
    }
    @Column(name = "CommentCount")
    public Integer getCommentCount() {
        return CommentCount;
    }

    public void setCommentCount(Integer commentCount) {
        CommentCount = commentCount;
    }
    @Column(name = "FavoriteCount")
    public Integer getFavoriteCount() {
        return FavoriteCount;
    }

    public void setFavoriteCount(Integer favoriteCount) {
        FavoriteCount = favoriteCount;
    }
    @Column(name = "Body")
    public String getBody() {
        return Body;
    }

    public void setBody(String body) {
        Body = body;
    }
    @Column(name = "Title")
    public String getTitle() {
        return Title;
    }

    public void setTitle(String title) {
        Title = title;
    }
    @Column(name = "Tags")
    public String getTags() {
        return Tags;
    }

    public void setTags(String tags) {
        Tags = tags;
    }

    @Temporal(TemporalType.DATE)
    @Column(name = "CreationDate")
    public Date getCreationDate() {
        return CreationDate;
    }

    public void setCreationDate(Date creationDate) {
        CreationDate = creationDate;
    }

    @Temporal(TemporalType.DATE)
    @Column(name = "LastEditDate")
    public Date getLastEditDate() {
        return LastEditDate;
    }

    public void setLastEditDate(Date lastEditDate) {
        LastEditDate = lastEditDate;
    }

    @Temporal(TemporalType.DATE)
    @Column(name = "LastActivityDate")
    public Date getLastActivityDate() {
        return LastActivityDate;
    }

    public void setLastActivityDate(Date lastActivityDate) {
        LastActivityDate = lastActivityDate;
    }

}

JSON结果的一部分:

{"parentPost":null,"acceptedAnswer":{"parentPost":{"parentPost":null,"acceptedAnswer":{"parentPost":{"parentPost":null,"acceptedAnswer":{"parentPost":{"parentPost":null,"acceptedAnswer":{"parentPost":{"parentPost":null,"acceptedAnswer":{"parentPost":{"parentPost":null,"acceptedAnswer":{"parentPost":{"parentPost":null,"acceptedAnswer":{"parentPost":{"parentPost":null,"acceptedAnswer":{"parentPost":{"parentPost":null,"acceptedAnswer":{"parentPost":{"parentPost":null,"acceptedAnswer":{"parentPost":{"parentPost":null,"acceptedAnswer":{"parentPost":{"parentPost":null,"acceptedAnswer":{"parentPost":{"parentPost":null,"acceptedAnswer":{"parentPost":{"parentPost":null,"acceptedAnswer":{"parentPost":{"parentPost":null,"acceptedAnswer":{"parentPost":{"parentPost":null,"acceptedAnswer":{"parentPost":{"parentPost":null,"acceptedAnswer":{"parentPost":{"parentPost":null,"acceptedAnswer":{"parentPost":{"parentPost":null,"acceptedAnswer":{"parentPost":{"parentPost":null,"acceptedAnswer":{"parentPost":

这显然会导致我的IDE无法响应。

我能够获得的部分例外:

at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:156)
at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:656)

1 个答案:

答案 0 :(得分:1)

您的Post个对象之一看起来有parentPost,而Post对象通过aceptedAnswer属性返回 xmlhttp.open("GET", "getstate.php"+str, true); 对象。

在这种情况下,当编组人员完成其工作时,没有必要停下来,因为它将在这两个对象之间无限循环来回。

这实际上取决于你想要实现的目标,但是对于marshaller透明的父帖子的引用看起来是最自然的方式,因为通常你首先考虑一个问题,然后寻找答案。但是,如果您从答案开始,然后查看原始问题的原因,您可能希望改为使用acceptAnswer。

无论如何,这样做的方式取决于你作为编组员的用途。例如,对于杰克逊,你会考虑使用

@JsonIgnore 要么 @JsonIgnoreProperties

Here一些例子如何使用。

希望有所帮助