1. 程式人生 > >hibernate關聯物件通過Springmvc轉json死迴圈

hibernate關聯物件通過Springmvc轉json死迴圈

在使用JPA+Springboot開發過程中,由於用到ajax非同步,在拿到資料後轉json過程中,出現棧溢位的迴圈,分析得出是物件關聯關係的問題。


在各種百度之後,得出的結論有很多


方法一:使用jsonIgnore註解

@JsonIgnoreProperties(value={"hibernateLazyInitializer","handler","user","handler","villagers","planDetails","attachments","town"})

通過忽略關聯關係來避免死迴圈。但是別太濫用,以至於所有entity都去用這個,根據需求用,否則,當你真很多地方都想要關聯關係時,就開始養bug了


方法二:使用set(null)

通過set  把 物件的關聯關係取消掉,即使從資料庫查出來了,也可以null,不關聯

比如A這個物件,有個user集合

a.setUsers(null);

這個,也還好,我沒試過,當時靈機一動想到的,如果setnull還死迴圈,好像有一個配置在application.properties 的引數可以避免  之前百度到,沒記住...提供個思路給大家



以上的方法其實並沒有直面問題,而是在逃避。

方法三:使用@JsonIdentityInfo(generator=ObjectIdGenerators.

UUIDGenerator.class,property="@id")

這個方法是我在百度的時候,找到的部落格,部落格地址:部落格

通過每個json加id  來達到認清父子關係。  部落格介紹的很詳細,可以去看看

加了這個可能還不行,最好加上@JsonIgnoreProperties(value={"hibernateLazyInitializer","handler"}  因為轉json過程中會出現因為懶載入而出現如下錯誤


org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver.handleHttpMessageNotWritable(407) | Failed to write HTTP message: org.springframework.http.converter.HttpMessageNotWritableException: Could not write content: No serializer found for class org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS) (through reference chain: java.util.HashMap["ckRequirePartLists"]->java.util.ArrayList[0]->com.dyoon.cmms.pojo.CkRequirePartList["ckPurchaseBill"]->com.dyoon.cmms.pojo.CkPurchaseBill["applyOperator"]->com.dyoon.cmms.pojo.UserOperator_

所以加上 @JsonIgnoreProperties(value={"hibernateLazyInitializer","handler"} 


最後貼個程式碼


import com.example.demo.domain.users.LoginUser;
import com.fasterxml.jackson.annotation.JsonBackReference;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonManagedReference;
import lombok.Getter;
import lombok.Setter;
import org.hibernate.annotations.Fetch;
import org.hibernate.annotations.FetchMode;
import org.hibernate.validator.constraints.NotEmpty;

import javax.persistence.*;
import javax.validation.constraints.NotNull;
import java.io.Serializable;
import java.util.Collection;
import java.util.List;

@Entity
@Getter
@Setter
@JsonIdentityInfo(generator=ObjectIdGenerators.UUIDGenerator.class, property="@id")
 @JsonIgnoreProperties(value={"hibernateLazyInitializer","handler"}
public class Committee extends NamedEntity implements Serializable {

    @NotNull
    private String bank;

    @NotEmpty
    private String account;

    @ManyToOne(cascade = CascadeType.PERSIST, fetch = FetchType.LAZY)
    @PrimaryKeyJoinColumn(name = "user_id")

    private LoginUser user;

    @OneToMany(mappedBy = "committee", cascade = {CascadeType.DETACH, CascadeType.MERGE, CascadeType.REFRESH})
    private Collection<Villager> villagers;

    @OneToMany(mappedBy = "committee", cascade = {CascadeType.DETACH,CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REFRESH})
    private Collection<PlanDetail> planDetails;

    @OneToMany(mappedBy = "committee", cascade = {CascadeType.DETACH, CascadeType.MERGE, CascadeType.REFRESH})
    @JsonBackReference
    private Collection<Plan> plans;

    @ManyToMany(mappedBy = "committees", cascade = CascadeType.ALL)
    private Collection<Attachment> attachments;

    @ManyToOne(cascade = CascadeType.PERSIST, fetch = FetchType.LAZY)
    @JoinColumn(name = "town_id")
    @Fetch(value = FetchMode.SELECT)

    private Town town;

    @Override
    public String toString() {
        return "[email protected]" + hashCode() +
                "(" + (isNew() ? "transient" : "persistent") + ")" +
                "[id=" + id +
                ", name=" + name +
                ", bank=" + bank +
                ", account=" + account +
                "]";
    }
}