【问题标题】:Java Hibernate json infinite recursion with self referencing classJava Hibernate json无限递归与自引用类
【发布时间】:2018-01-03 20:42:18
【问题描述】:

班级员工:

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

(然后继续)

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

【问题讨论】:

    标签: java json spring hibernate object


    【解决方案1】:

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

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

    @Getter
    @Setter
    @NoArgsConstructor
    public class OutboundGoodsTypeDTO extends OutboundEntityDTO {
    
      @JsonManagedReference
      private OutboundGoodsTypeDTO parent;
    
      @JsonBackReference
      private Set<OutboundGoodsTypeDTO> goodsTypes;
    }
    

    来自文档:

    @JsonManagedReference

    注解用于表明被注解的属性是双向的一部分 领域之间的联系;并且它的角色是“父母”(或“转发”) 链接。

    @JsonBackReference

    用于指示关联属性是一部分的注释 字段之间的双向链接;并且它的角色是“孩子”(或 "返回") 链接。

    【讨论】:

      【解决方案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

      【讨论】:

        猜你喜欢
        • 2018-10-02
        • 1970-01-01
        • 2023-03-26
        • 1970-01-01
        • 2017-07-27
        • 2011-03-20
        相关资源
        最近更新 更多