Весенние данные jpa @OneToMany двунаправленные в одной таблице

#spring #jpa #spring-data-jpa #spring-data

Вопрос:

Я пытаюсь создать простое сопоставление для одного табличного отношения, такого как схема организации. Я использую Spring Boot с данными Spring и JPA. Это моя Сущность:

 @Entity
@Table(name = "orgchart")
public class OrgChart {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private long id;

    @ManyToOne
    private OrgChart parent;

    @OneToMany
    @JoinColumn(name = "parent_id")
    private List<OrgChart> children = new ArrayList<>();
}
 

и тестовый код для добавления некоторых данных:

 OrgChart orgChart = new OrgChart();

OrgChart orgChart1 = new OrgChart();
orgChartRepository.save(orgChart1);

OrgChart orgChart2 = new OrgChart();
orgChartRepository.save(orgChart2);

orgChart.getChildren().add(orgChart1);
orgChart.getChildren().add(orgChart2);
OrgChart saved = orgChartRepository.save(orgChart);
 

таким образом, таблица создана правильно, и структура также выглядит нормально для меня:

 id |parent_id|
--- --------- 
361|         |
359|      361|
360|      361|
 

но проблема в том, что я не вижу родительского поля в объекте, когда я извлекаю его из базы данных:

 List<OrgChart> children = orgChartRepository.getById(saved.getId()).getChildren()
 

здесь children.get(0).getParent() всегда значение null. Что я делаю не так? Я уже перепробовал так много способов, возможно ли этого достичь?
Спасибо.

Ответ №1:

Попробуйте @OneToMany(mappedBy="parent") сказать JPA, что эти поля являются двумя концами двунаправленных отношений, а не двумя разными однонаправленными.

Комментарии:

1. это не работает

2. Это может быть связано с тем, что при сохранении двунаправленных отношений вам необходимо указать сторону владельца . В этом случае сторона владельца-это parent поле, поэтому, пожалуйста, попробуйте orgChart1.setParent(orgChart) перед сохранением orgChart1 .

3. если я установлю родителя, то при извлечении данных я буду видеть только родителя, а не детей. Если я установлю оба параметра, я получу ошибку stackoverflow.

Ответ №2:

Для этого необходимо выполнить следующее:

     @OneToMany(cascade = CascadeType.ALL, mappedBy="parent", orphanRemoval = true)
    private List<OrgChart> children = new ArrayList<>();
    
    @ManyToOne
    @JoinColumn(name = "parent_id")
    private OrgChart parent;
    
    OrgChart parent = new OrgChart();
    OrgChart newOrgChart = new OrgChart();
    newOrgChart.setParent(parent);
    parent.getChildren().add(newOrgChart);