Java Hibernate json无限递归与自引用类

时间:2017-07-27 22:56:53

标签: java json spring hibernate object

班级员工:

@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
}

每当我创建一个员工实例时,我都会遇到这个无限的json错误:

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)

(然后它继续前进)

由于我是自我引用经理,这是员工类中的员工,我该如何解决这个问题?

2 个答案:

答案 0 :(得分:2)

有很多选择取决于您的要求:

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

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

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

@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您可以自行确定构建JSON对象的规则。

4)在类上使用@JsonIdentityInfo(表示该类型的属性应启用了功能)以及单个属性(以支持无法对类型本身进行注释的情况;或使用不同的id生成序列。)

Example 1 @JsonIdentityInfo

Example 2 @JsonIdentityInfo

答案 1 :(得分:0)

我知道这个问题很古老,但是以防万一有人偶然发现了这个问题。

您将注释的顺序错误。这是我的示例:

@Getter
@Setter
@NoArgsConstructor
public class OutboundGoodsTypeDTO extends OutboundEntityDTO {

  @JsonManagedReference
  private OutboundGoodsTypeDTO parent;

  @JsonBackReference
  private Set<OutboundGoodsTypeDTO> goodsTypes;
}

从文档中:

@JsonManagedReference

  

用于指示带注释的属性是双向属性的一部分的注释   领域之间的联系;并且其角色是“父母”(或“前进”)   链接。

@JsonBackReference

  

用于指示关联属性是的一部分的注释   领域之间的双向联系;并且其角色是“孩子”(或   “后退”)链接。