JPA: отношения OneToMany сохраняют коллекцию пустой - PullRequest
0 голосов
/ 02 января 2019

Кажется, мне трудно понять JPA и как на самом деле работают отношения OneToMany.

Например, представьте, что у меня есть объект Class

@Entity
public class Class {
    @Id
    private String className;

    @OneToMany(cascade = Cascade.ALL, orphanRemoval = true)
    private Set<Student> students;

    // Constructors, Getters, Setter
}

У меня также естьобъект Student, где он содержит класс.

@Entity
public class Student {
    @Id
    private String studentName;

    @ManyToOne
    private Class class;

    // Constructors, Getters, Setter
}

Очевидно, ученик может иметь несколько классов, но забывать об этом.

Почему, когда я строю класс, а затем собираю пару учеников, используя этот класс, findAll() на ClassRepository возвращает мне пустой набор учеников.

Class class = new Class("CS", new HashSet<>());
classRepository.save(class); // repository has no special functions

Student student1 = new Student("1", class);
Student student2 = new Student("2", class);

studentRepository.save(student1);
studentRepository.save(student2);

classRepository.findAll() // Returns me a List<Class> with only one class object that has an empty set.

IЯ думал, что приведенный выше код должен автоматически увидеть, что эти два ученика принадлежат к одному классу, и поэтому, когда я вызываю buildingRepository.findAll(), он вернет объект Class с заполненными наборами учеников.

Это мое пониманиенеправильно тогда?Или мой код неверен?И как я могу изменить это, чтобы исправить это?

1 Ответ

0 голосов
/ 02 января 2019

Вы можете выбрать:

1.Однонаправленный @OneToMany:

@Entity
public class Class {
    @Id
    private String className;

    @OneToMany(cascade = Cascade.ALL, orphanRemoval = true)
    private List<Student> students=new ArrayList<>();

    // Constructors, Getters, Setter
}

@Entity
public class Student {
    @Id
    private String studentName;

    // Constructors, Getters, Setter
}

Теперь, если мы сохраним один Class:

Class class1=new Class("name1");
class1.getStudents().add(new Student("student1Name"));
// then you can make a save of class1 in db
classRepository.save(class);

2.Однонаправленный @OneToMany с @JoinColumn:

Чтобы исправить вышеупомянутую проблему с дополнительной таблицей соединений, нам просто нужно добавить @JoinColumn в микс:

@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
@JoinColumn(name = "class_id")
private List<Student> students = new ArrayList<>();

3.Двунаправленный @OneToMany:

Лучший способ отобразить связь @OneToMany - это полагаться на сторону @ManyToOne для распространения всех изменений состояния сущности:

@Entity
public class Class {
    @Id
    private String className;

    @OneToMany(
        mappedBy = "class",
        cascade = CascadeType.ALL,
        orphanRemoval = true
    )
    private List<Student> students=new ArrayList<>();

    // Constructors, Getters, Setter
    public void addStudent(Student student) {
        students.add(student);
        student.setClass(this);
    }

    public void removeStudent(Student student) {
        students.remove(student);
        student.setClass(null);
    }
}


@Entity
public class Student {
    @Id
    private String studentName;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "class_id")
    private Class class;

}

И сохраняться:

Class c1=new Class("className1");
c1.addStudent(new Student("StudentNAme1"));
c1.addStudent(new Student("StudentNAme2"));
c1.addStudent(new Student("StudentNAme3"));
classRepository.save(c1);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...