1

私はHibernate 5.2.7を使用しています。最終的なHibernate APIです。今Hibernateの再帰的マッピングの親子構造 - データを取得するときのStackOverflowError

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

:私は成功したマネージャーと従業員との持続

+------------+--------------+------+-----+---------+-------+ 
| 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 |  | 
+------------+--------------+------+-----+---------+-------+ 

:以下の表は、休止状態で作成された

@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エンティティを持っています従業員を取得すると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オブジェクトグラフを永続化することができる方法はとても便利だと思います。しかし、私はどのようにテーブルからそのようなグラフを取得するのか分かりません。

質問:基本的なテーブルから従業員情報を意味のある方法で取得するにはどうすればよいですか。私はその周りの方法は、従業員のテーブルを表示するための新しいエンティティを作成することだと思う

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

私はこれを達成することはできますか? JPA注釈の使い方は?

+0

あなたは 'StackOverflowError'スタックトレースを含めることができますか?また、これを5.2.7で再現できないため、Hibernateのどのバージョンをテストしていますか。 – Naros

+0

私はスタックトレースを含んでいます。私は、StackOverflowErrorは従業員オブジェクトがフェッチされたときに発生し、休止状態でマネージャをフェッチしようとし、マネージャはその従業員をその従属リストに入れていると考えられます。私は@ManyToOne(fetch = FetchType.LAZY)を試したが、役に立たなかった。 –

答えて

1

Employeeエンティティでは、問題がtoString()メソッドであると思われます。

コードを入力していないので、より一般化されたParentChildの見方の間でこれがどうなるかの明確な例がここにあります。

今どこかのコードでは、このあり
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()); 

ParentへのコールバックParentからChildた代表団にダウン委任うと厄介なサイクルが続くので、これは、同じオーバーフローの問題を引き起こします。

あなたのケースで最も論理的な意味を持つものを決める必要があります。この再帰的ループを避けるために、スキップするか、関連するエンティティの識別子のみを表示するかのどちらかです。

+0

あなたは正しいです。私はそのような厄介なtoString()を持っています。あなたの洞察力に感謝します。 –

関連する問題