Hibernate递归映射父/子结构-检索数据时StackOverflower错误

Hibernate递归映射父/子结构-检索数据时StackOverflower错误,hibernate,recursion,parent-child,hibernate-mapping,jpa-annotations,Hibernate,Recursion,Parent Child,Hibernate Mapping,Jpa Annotations,我正在使用Hibernate 5.2.7.Final和本机Hibernate API。 我有一个具有递归关系的雇员实体: @Entity public class Employee { @Id @GeneratedValue private Long employeeId; @Column private String firstname; @Column private String lastname; @ManyToOn

我正在使用Hibernate 5.2.7.Final和本机Hibernate API。 我有一个具有递归关系的雇员实体:

@Entity
public class Employee {

    @Id
    @GeneratedValue
    private Long employeeId;

    @Column
    private String firstname;

    @Column
    private String lastname;

    @ManyToOne(cascade={ CascadeType.ALL})
    @JoinColumn(name="manager_id")
    private Employee manager;

    @OneToMany(mappedBy="manager", cascade = CascadeType.ALL)
    private Set<Employee> subordinates = new HashSet<Employee>();
    // setters, getters, constructors
}
我成功地向经理和员工传达了以下信息:

    Employee manager = new Employee("A", "B");

    Employee employee1 = new Employee("C", "D");
    Employee employee2 = new Employee("E", "E");

    employee1.setManager(manager1);
    employee2.setManager(manager1);

    Set<Employee> employees = new HashSet<>();
    employees.add(employee1);
    employees.add(employee2);

    manager.setSubordinates(employees);

    session.save(manager);
我认为我可以保存这样的Employee对象图的方法非常方便。但我不知道如何从表中检索这样的图形

问题:如何从基础表中有意义地检索员工信息。我认为解决方法是创建一个新实体来查看Employee表,如

    public class EmployeeView {
            private Long employeeId;
            private String firstname;
            private String manager_name;
            private Set<String> subordinate_names;
    }
公共类EmployeeView{
私人长期雇员ID;
私有字符串名;
私有字符串管理器\u名称;
私有设置从属名称;
}

我能做到这一点吗?如何使用JPA注释?

我怀疑问题出在您的
员工
实体中的
toString()
方法

由于您没有提供任何代码,下面是一个清晰的示例,说明了如何从更广义的角度看待
父对象
子对象

public class Parent {
  @OneToMany(mappedBy = "parent");
  List<Child> children;

  @Override
  public String toString() {
    StringBuilder sb = new StringBuilder();
    sb.append( "Parent{children=" );
    children.forEach( sb::apend );
    sb.append( "}" );
    return sb.toString();
}

public class Child {
  @ManyToOne
  private Parent parent;

  @Override
  public String toString() {
    return "Child{parent=" + parent + "}";
  }
}
这将导致相同的溢出问题,因为对
Parent
的调用将向下委托到
Child
,这将委托回
Parent
,并且讨厌的循环将继续


您需要决定在您的案例中哪个最符合逻辑,并且可能跳过或仅打印关联实体的标识符以避免此递归循环。

是否可以包括
stackoverflowerrror
堆栈跟踪?另外,由于我无法在5.2.7.Final上复制,您在哪个版本的Hibernate上测试这个。我已经包括了堆栈跟踪。我认为StackOverflowerError是在提取employee对象时引起的,hibernate尝试提取其经理,而经理又在其下属列表中包含这样的员工。我试过@ManyToOne(fetch=FetchType.LAZY),但是没有用。你是对的。我有一个非常讨厌的东西。非常感谢您的洞察力。
at java.lang.Long.toString(Long.java:396)
at java.lang.Long.toString(Long.java:1032)
at java.lang.String.valueOf(String.java:2994)
at java.lang.StringBuilder.append(StringBuilder.java:131)
at objectModels.Employee.toString(Employee.java:82)
at java.lang.String.valueOf(String.java:2994)
at java.lang.StringBuilder.append(StringBuilder.java:131)
at objectModels.Employee.toString(Employee.java:82)
at java.lang.String.valueOf(String.java:2994)
at java.lang.StringBuilder.append(StringBuilder.java:131)
at objectModels.Employee.toString(Employee.java:82)
at java.lang.String.valueOf(String.java:2994)
at java.lang.StringBuilder.append(StringBuilder.java:131)
at objectModels.Employee.toString(Employee.java:82)
at java.lang.String.valueOf(String.java:2994)
at java.lang.StringBuilder.append(StringBuilder.java:131)
at objectModels.Employee.toString(Employee.java:82)
at java.lang.String.valueOf(String.java:2994)
at java.lang.StringBuilder.append(StringBuilder.java:131)
at objectModels.Employee.toString(Employee.java:82)
at java.lang.String.valueOf(String.java:2994)
at java.lang.StringBuilder.append(StringBuilder.java:131)
at objectModels.Employee.toString(Employee.java:82)
at java.lang.String.valueOf(String.java:2994)
at java.lang.StringBuilder.append(StringBuilder.java:131)
at objectModels.Employee.toString(Employee.java:82)
at java.lang.String.valueOf(String.java:2994)
at java.lang.StringBuilder.append(StringBuilder.java:131)
at objectModels.Employee.toString(Employee.java:82)
at java.lang.String.valueOf(String.java:2994)
at java.lang.StringBuilder.append(StringBuilder.java:131)
at objectModels.Employee.toString(Employee.java:82)
at java.lang.String.valueOf(String.java:2994)
at java.lang.StringBuilder.append(StringBuilder.java:131)
at objectModels.Employee.toString(Employee.java:82)
at java.lang.String.valueOf(String.java:2994)
at java.lang.StringBuilder.append(StringBuilder.java:131)
at objectModels.Employee.toString(Employee.java:82)
at java.lang.String.valueOf(String.java:2994)
at java.lang.StringBuilder.append(StringBuilder.java:131)
at objectModels.Employee.toString(Employee.java:82)
at java.lang.String.valueOf(String.java:2994)
at java.lang.StringBuilder.append(StringBuilder.java:131)
at objectModels.Employee.toString(Employee.java:82)
at java.lang.String.valueOf(String.java:2994)
at java.lang.StringBuilder.append(StringBuilder.java:131)
at objectModels.Employee.toString(Employee.java:82)
at java.lang.String.valueOf(String.java:2994)
at java.lang.StringBuilder.append(StringBuilder.java:131)
at objectModels.Employee.toString(Employee.java:82)
at java.lang.String.valueOf(String.java:2994)
at java.lang.StringBuilder.append(StringBuilder.java:131)
at objectModels.Employee.toString(Employee.java:82)
at java.lang.String.valueOf(String.java:2994)
at java.lang.StringBuilder.append(StringBuilder.java:131)
at objectModels.Employee.toString(Employee.java:82)
at java.lang.String.valueOf(String.java:2994)
at java.lang.StringBuilder.append(StringBuilder.java:131)
at objectModels.Employee.toString(Employee.java:82)
at java.lang.String.valueOf(String.java:2994)
at java.lang.StringBuilder.append(StringBuilder.java:131)
at objectModels.Employee.toString(Employee.java:82)
at java.lang.String.valueOf(String.java:2994)
at java.lang.StringBuilder.append(StringBuilder.java:131)
at objectModels.Employee.toString(Employee.java:82)
at java.lang.String.valueOf(String.java:2994)
at java.lang.StringBuilder.append(StringBuilder.java:131)
at objectModels.Employee.toString(Employee.java:82)
at java.lang.String.valueOf(String.java:2994)
at java.lang.StringBuilder.append(StringBuilder.java:131)
at objectModels.Employee.toString(Employee.java:82)
at java.lang.String.valueOf(String.java:2994)
at java.lang.StringBuilder.append(StringBuilder.java:131)
at objectModels.Employee.toString(Employee.java:82)
at java.lang.String.valueOf(String.java:2994)
at java.lang.StringBuilder.append(StringBuilder.java:131)
at objectModels.Employee.toString(Employee.java:82)
at java.lang.String.valueOf(String.java:2994)
at java.lang.StringBuilder.append(StringBuilder.java:131)
at objectModels.Employee.toString(Employee.java:82)
at java.lang.String.valueOf(String.java:2994)
at java.lang.StringBuilder.append(StringBuilder.java:131)
at objectModels.Employee.toString(Employee.java:82)
at java.lang.String.valueOf(String.java:2994)
at java.lang.StringBuilder.append(StringBuilder.java:131)
at objectModels.Employee.toString(Employee.java:82)
at java.lang.String.valueOf(String.java:2994)
at java.lang.StringBuilder.append(StringBuilder.java:131)
at objectModels.Employee.toString(Employee.java:82)
at java.lang.String.valueOf(String.java:2994)
at java.lang.StringBuilder.append(StringBuilder.java:131)
at objectModels.Employee.toString(Employee.java:82)
at java.lang.String.valueOf(String.java:2994)
at java.lang.StringBuilder.append(StringBuilder.java:131)
at objectModels.Employee.toString(Employee.java:82)
at java.lang.String.valueOf(String.java:2994)
at java.lang.StringBuilder.append(StringBuilder.java:131)
at objectModels.Employee.toString(Employee.java:82)
at java.lang.String.valueOf(String.java:2994)
at java.lang.StringBuilder.append(StringBuilder.java:131)
at objectModels.Employee.toString(Employee.java:82)
at java.lang.String.valueOf(String.java:2994)
at java.lang.StringBuilder.append(StringBuilder.java:131)
at objectModels.Employee.toString(Employee.java:82)
at java.lang.String.valueOf(String.java:2994)
at java.lang.StringBuilder.append(StringBuilder.java:131)
at objectModels.Employee.toString(Employee.java:82)
at java.lang.String.valueOf(String.java:2994)
at java.lang.StringBuilder.append(StringBuilder.java:131)
at objectModels.Employee.toString(Employee.java:82)
at java.lang.String.valueOf(String.java:2994)
at java.lang.StringBuilder.append(StringBuilder.java:131)
at objectModels.Employee.toString(Employee.java:82)
at java.lang.String.valueOf(String.java:2994)
at java.lang.StringBuilder.append(StringBuilder.java:131)
at objectModels.Employee.toString(Employee.java:82)
at java.lang.String.valueOf(String.java:2994)
at java.lang.StringBuilder.append(StringBuilder.java:131)
at objectModels.Employee.toString(Employee.java:82)
at java.lang.String.valueOf(String.java:2994)
at java.lang.StringBuilder.append(StringBuilder.java:131)
at objectModels.Employee.toString(Employee.java:82)
at java.lang.String.valueOf(String.java:2994)
at java.lang.StringBuilder.append(StringBuilder.java:131)
at objectModels.Employee.toString(Employee.java:82)
at java.lang.String.valueOf(String.java:2994)
at java.lang.StringBuilder.append(StringBuilder.java:131)
at objectModels.Employee.toString(Employee.java:82)
at java.lang.String.valueOf(String.java:2994)
at java.lang.StringBuilder.append(StringBuilder.java:131)
at objectModels.Employee.toString(Employee.java:82)
at java.lang.String.valueOf(String.java:2994)
at java.lang.StringBuilder.append(StringBuilder.java:131)
at objectModels.Employee.toString(Employee.java:82)
at java.lang.String.valueOf(String.java:2994)
at java.lang.StringBuilder.append(StringBuilder.java:131)
at objectModels.Employee.toString(Employee.java:82)
at java.lang.String.valueOf(String.java:2994)
at java.lang.StringBuilder.append(StringBuilder.java:131)
at objectModels.Employee.toString(Employee.java:82)
at java.lang.String.valueOf(String.java:2994)
    public class EmployeeView {
            private Long employeeId;
            private String firstname;
            private String manager_name;
            private Set<String> subordinate_names;
    }
public class Parent {
  @OneToMany(mappedBy = "parent");
  List<Child> children;

  @Override
  public String toString() {
    StringBuilder sb = new StringBuilder();
    sb.append( "Parent{children=" );
    children.forEach( sb::apend );
    sb.append( "}" );
    return sb.toString();
}

public class Child {
  @ManyToOne
  private Parent parent;

  @Override
  public String toString() {
    return "Child{parent=" + parent + "}";
  }
}
System.out.println( parent.toString() );