本文介绍了Java Hibernate使用自引用类的无限递归的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

班级员工:

  @Entity 
@Table(name =Employee)
public class Employee {

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name =EmployeeID)
private int EmployeeID;

@Column(name =ManagerID)
Private Integer ManagerID;

@ManyToOne(cascade = {CascadeType.ALL})
@JoinColumn(name =ManagerID,insertable = false,updatable = false)
@JsonBackReference
私人员工经理;

@OneToMany(mappedBy =manager)
@JsonManagedReference
private Set< Employee>雇员;

@ManyToOne(cascade = {CascadeType.ALL})
@JoinColumn(name =DepartmentID)
私人部门部门;

@ManyToOne(cascade = {CascadeType.ALL})
@JoinColumn(name =SalaryTypeID)
private SalaryType salaryType;

@Column(name =Name)
private String Name;
// setters and getters here,would not be posting them
}

每当我创建了一个员工实例,我得到了这个无限的json错误:
$ b $ pre $ SEVERE:Servlet.service()for servlet [SpringMVC] in上下文路径
[/ SpringMVC]抛出异常[Handler processing failed;嵌套异常是
java.lang.StackOverflowError],其根源为
java.lang.StackOverflowError $ b $ java.nio.CharBuffer。< init>(Unknown Source)
at java .nio.HeapCharBuffer。< init>(未知来源)
在java.nio.CharBuffer.wrap(未知来源)
在sun.nio.cs.StreamEncoder.implWrite(未知来源)
在sun.nio.cs.StreamEncoder.write(未知源)
在sun.nio.cs.StreamEncoder.write(未知源)
在java.io.OutputStreamWriter.write(未知源)
在java.io.Writer.write(未知源)
在com.google.gson.stream.JsonWriter.string(JsonWriter.java:534)
在com.google.gson.stream .JsonWriter.writeDeferredName(JsonWriter.java:402)
at com.google.gson.stream.JsonWriter.value(JsonWriter.java:495)

解决方案

有是一堆选择取决于您的要求:



1) @JsonIgnore 可以用于避免字段的序列化。

  @OneToMany(mappedBy =manager)
@JsonIgnore
私人套餐<员工>雇员;

2) @JsonView 可隐藏关系的一部分作为内部视图(但如果您将使用内部视图)编写JSON对象,则会出现:

  @OneToMany(mappedBy =manager)
@JsonView(Views.Internal.class)
private Set< Employee>雇员;

@ManyToOne(cascade = {CascadeType.ALL})
@JoinColumn(name =DepartmentID)
@JsonView(Views.Public.class)
private部门部门;

3) ,您可以确定自己构建JSON对象的规则。



4)在类上使用 @JsonIdentityInfo (以指示该类型的属性应该启用功能)以及单独的属性(以支持类型本身不能被注释的情况;或者使用不同的id生成序列)。




class employee:

@Entity
@Table(name = "Employee")
public class Employee {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "EmployeeID")
    private int EmployeeID;

    @Column(name = "ManagerID")
    private Integer ManagerID;

    @ManyToOne(cascade={CascadeType.ALL})
    @JoinColumn(name="ManagerID", insertable = false, updatable = false)
    @JsonBackReference
    private Employee manager;

    @OneToMany(mappedBy="manager")
    @JsonManagedReference
    private Set<Employee> employees;

    @ManyToOne(cascade={CascadeType.ALL})
    @JoinColumn(name = "DepartmentID")
    private Department department;

    @ManyToOne(cascade={CascadeType.ALL})
    @JoinColumn(name = "SalaryTypeID")
    private SalaryType salaryType;

    @Column(name = "Name")
    private String Name;
    //setters and getters here, wont be posting them
}

Whenever I create an instance of employee I get this infinite json error:

SEVERE: Servlet.service() for servlet [SpringMVC] in context with path
[/SpringMVC] threw exception [Handler processing failed; nested exception is
java.lang.StackOverflowError] with root cause
java.lang.StackOverflowError
at java.nio.CharBuffer.<init>(Unknown Source)
at java.nio.HeapCharBuffer.<init>(Unknown Source)
at java.nio.CharBuffer.wrap(Unknown Source)
at sun.nio.cs.StreamEncoder.implWrite(Unknown Source)
at sun.nio.cs.StreamEncoder.write(Unknown Source)
at sun.nio.cs.StreamEncoder.write(Unknown Source)
at java.io.OutputStreamWriter.write(Unknown Source)
at java.io.Writer.write(Unknown Source)
at com.google.gson.stream.JsonWriter.string(JsonWriter.java:534)
at com.google.gson.stream.JsonWriter.writeDeferredName(JsonWriter.java:402)
at com.google.gson.stream.JsonWriter.value(JsonWriter.java:495)

(and then it keeps going)

Since I am self referencing manager which is an employee in the employee class, how can I fix this?

解决方案

There are bunch of options depends on your requirement:

1) @JsonIgnore can be used to avoid serialization of the field.

@OneToMany(mappedBy="manager")
@JsonIgnore
private Set<Employee> employees;

2) @JsonView can hide one part of the relationship as internal view (but will appear if you will write JSON object with Internal view):

@OneToMany(mappedBy="manager")
@JsonView(Views.Internal.class)
private Set<Employee> employees;

@ManyToOne(cascade={CascadeType.ALL})
@JoinColumn(name = "DepartmentID")
@JsonView(Views.Public.class)
private Department department;

3) Using custom serialiazer you can determine the rules of building your JSON object yourself.

4) Using @JsonIdentityInfo on classes (to indicate that properties of that type should have feature enabled) as well as on individual properties (to support cases where type itself can not be annotated; or to use different id generation sequence).

Example 1 @JsonIdentityInfo

Example 2 @JsonIdentityInfo

这篇关于Java Hibernate使用自引用类的无限递归的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-11 06:27