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 villagers;

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

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

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

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

    private Town town;

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






你可能感兴趣的:(JAVA,Maven,ssh)