3

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

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

下表是由hibernate创建的:

+------------+--------------+------+-----+---------+-------+
| Field      | Type         | Null | Key | Default | Extra |
+------------+--------------+------+-----+---------+-------+
| employeeId | bigint(20)   | NO   | PRI | NULL    |       |
| firstname  | varchar(255) | YES  |     | NULL    |       |
| lastname   | varchar(255) | YES  |     | NULL    |       |
| manager_id | bigint(20)   | YES  | MUL | NULL    |       |
+------------+--------------+------+-----+---------+-------+

我成功地坚持经理和员工:

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

现在检索员工将导致 StackOverFlowError。

    Long id = manager.getEmployeeId();

    Query<Employee> query = ss.createQuery("from Employee e where e.employeeId = :employeeId", Employee.class);

    query.setParameter("employeeId", id);

    Employee retrieved = (Employee) query.uniqueResult();

线程“主”java.lang.StackOverflowError 中的异常

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)

我认为我可以坚持这样的 Employee 对象图的方式非常方便。但我不知道如何从表中检索这样的图表。

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

    public class EmployeeView {
            private Long employeeId;
            private String firstname;
            private String manager_name;
            private Set<String> subordinate_names;
    }

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

4

1 回答 1

3

我怀疑问题是toString()Employee实体中的方法。

由于您没有提供任何代码,因此这里有一个清晰的示例,说明在 aParent和的更广义的视角之间如何发生这种情况Child

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() );

这将导致同样的溢出问题,因为调用 inParent会向下Child委托给哪个委托,Parent并且令人讨厌的循环继续。

您需要决定哪个在您的情况下最合乎逻辑,并且可能跳过或仅打印关联实体的标识符以避免这种递归循环。

于 2017-02-11T17:04:53.340 回答