Java – JPA : OneToMany relationship keeps the Collection empty

JPA : OneToMany relationship keeps the Collection empty… here is a solution to the problem.

JPA : OneToMany relationship keeps the Collection empty

It seems difficult for me to understand JPA and how OneToMany relationships actually work.

For example, suppose I have an object Class

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

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

 Constructors, Getters, Setter
}

I also have an object, Student, which contains Class.

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

@ManyToOne
    private Class class;

 Constructors, Getters, Setter
}

Obviously, a student can have multiple classes, but leave this alone.

Why does findAll() on the ClassRepository return a set of empty students when I create a class and then use that class to create several students.

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

was thinking the above code should automatically see that the two students are from that class, so when I call buildingRepository.findAll(), it returns a Class object that correctly populates the student set.

So did I misunderstand? Or is my code wrong? How do I change it to fix it?

Solution

You can choose:

1。 One-way @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
}

Now, if we stick to a 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。 One-way @OneToMany with @JoinColumn:

To solve the extra join table problem mentioned earlier, we just need to add @JoinColumn: to the mix

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

3。 Bidirectional @OneToMany:

The best way to map @OneToMany associations is to rely on the @ManyToOne side to propagate all entity state changes:

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

}

And insist:

Class c1=new Class("className1");
c1.addStudent(new Student("StudentNAme1"));
c1.addStudent(new Student("StudentNAme2"));
c1.addStudent(new Student("StudentNAme3"));
classRepository.save(c1);

Related Problems and Solutions