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.
這個方法是我在百度的時候,找到的部落格,部落格地址:部落格
通過每個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 +
"]";
}
}