Spring JPA,MySQL-无法写入内容:通过引用链无限递归StackOverflowError

时间:2016-03-16 17:29:42

标签: java spring hibernate jpa

我想知道我在这里做错了什么,因为我已经完成了加载类型,它不是递归的。但是我收到以下错误。当我尝试从访问对象访问getServerRequest()方法时。

  

WARN 6511 --- [nio-8080-exec-2]   .w.s.m.s.DefaultHandlerExceptionResolver:写入HTTP失败   信息:   org.springframework.http.converter.HttpMessageNotWritableException:   无法写内容:无限递归(StackOverflowError)   (通过参考链:   com.biscoind.domain.ServerRequest [ “访问”] - GT; org.hibernate.collection.internal.PersistentBag [0] - > com.biscoind.domain.Visit [ “请求”] - > com.biscoind.domain .ServerRequest [ “访问”] - GT; org.hibernate.collection.internal.PersistentBag [0] - > com.biscoind.domain.Visit [ “请求”] - > com.biscoind.domain.ServerRequest [“访问“] - > org.hibernate.collection.internal.PersistentBag [0] - > com.biscoind.domain.Visit [” 请求 “] - > com.biscoind.domain.ServerRequest [” 访问“] - GT; org.hibernate.collection.internal.PersistentBag [0] - > com.biscoind.domain.Visit [ “请求”] - > com.biscoind.domain.ServerRequest [ “访问”] - GT; org.hibernate.collection .internal.PersistentBag [0] - > com.biscoind.domain.Visit [ “请求”] - > com.biscoind.domain.ServerRequest [ “访问”] - GT; org.hibernate.collection.internal.PersistentBag [ 0] - > com.biscoind.domain.Visit [ “请求”] - > com.biscoind.domain.ServerRequest [ “访问”] - GT; org.hibernate.collection.internal.PersistentBag [0] - > com.biscoind.domain.Visit [“reques吨 “] - > com.biscoind.domain.ServerRequest [” 访问 “] - GT; org.hibernate.collection.internal.PersistentBag [0] - > com.biscoind.domain.Visit [” 请求“] - &GT ; com.biscoind.domain.ServerRequest [ “访问”] - GT; org.hibernate.collection.internal.PersistentBag [0] - >

我有以下映射类,

@Entity
@Table(name = "server_request")
public class ServerRequest {

    private Long id;
    private Date createdDate;
    private Date lastUpdatedDate;

    private List<Visit> visits = new ArrayList<Visit>();

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "server_request_id")
    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    @OneToMany(fetch = FetchType.LAZY, mappedBy = "request", cascade = CascadeType.ALL)
    public List<Visit> getVisits() {
        return visits;
    }

    public void setVisits(List<Visit> visits) {
        this.visits = visits;
    }

    public Date getCreatedDate() {
        return createdDate;
    }

    public void setCreatedDate(Date createdDate) {
        this.createdDate = createdDate;
    }

    public Date getLastUpdatedDate() {
        return lastUpdatedDate;
    }

    public void setLastUpdatedDate(Date lastUpdatedDate) {
        this.lastUpdatedDate = lastUpdatedDate;
    }
}

@Entity
@Table(name = "user_visit")
public class Visit implements Serializable {

    private static final long serialVersionUID = 1L;

    private Long id;
    private ServerRequest request;
    private String status;
    private Date date;

    public Date getDate() {
        return date;
    }

    public void setDate(Date date) {
        this.date = date;
    }

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "user_visit_id")
    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn(name = "server_request_id", referencedColumnName = "server_request_id", nullable = false)
    public ServerRequest getRequest() {
        return request;
    }

    public void setRequest(ServerRequest request) {
        this.request = request;
    }

}

2 个答案:

答案 0 :(得分:5)

如果您正在使用Jackson并且转换器正在尝试编写JSON(堆栈没有明确说明),请在@JsonIdentityInfo方法上添加getRequest()注释。

@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property="id", scope=ServerRequest.class)
@ManyToOne(fetch = FetchType.EAAGER)
@JoinColumn(name = "server_request_id", referencedColumnName = "server_request_id", nullable = false)
public ServerRequest getRequest() {
    return request;
}

这是Jackson在序列化/反序列化期间解析对象图中循环依赖的方式。

一些提示:

  • 您无需声明FetchType.LAZY。这是默认完成的。
  • 在您的ManyToOne上,从FetchType.EAAGER变为FetchType.EAGER

答案 1 :(得分:0)

  1. 您可以使用@ManyToOne(fetch = FetchType.EAAGER)打破周期。

  2. 检查代码中是否正确写入:<rules> <rule> <key> </key> <name> </name> <description> </description> </rule> </rules>