Home > Mobile >  How to save entity Many-to-Many With a New Entity with with extra columns in SpringBoot
How to save entity Many-to-Many With a New Entity with with extra columns in SpringBoot

Time:09-24

I have to save entity Student with Course entity, but I have an extra Entity class StudentCourse to put starting date of the course and ending date. How to persist all data at once? This is my code until now:

@Entity
public class Student{

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "student_id")
    private Integer id;
    private String firstName;
    private String lastName;
    @OneToMany(mappedBy = "student")
    Set<StudentCourse> studentCourses;

//have getter and setters and overridden hashCode() and equals
}
@Entity
public class StudentCourse {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;

    @ManyToOne
    @JoinColumn(name = "student_id")
    Student student;
    @ManyToOne
    @JoinColumn(name = "course_id")
    Course course;
    private Date startDate;
    private Date endDate;
}
@Entity
public class Course {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "course_id")
    private Integer id;
    private String name;
    private String description;

    @OneToMany(mappedBy = "course")
    Set<StudentCourse> studentCourses;

}

I need to save entity student with Set of courses, also I need to add the start date and end date into the StudentCourse table. I m using the JpaRepository interface.

CodePudding user response:

You need to add cascade to @OneToMany and @ManyToOne annotations as follows:

@Entity
public class Student{

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "student_id")
    private Integer id;
    private String firstName;
    private String lastName;
    @OneToMany(mappedBy = "student", cascade = CascadeType.ALL)
    Set<StudentCourse> studentCourses;

//have getter and setters and overridden hashCode() and equals
}
@Entity
public class StudentCourse {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;

    @ManyToOne
    @JoinColumn(name = "student_id")
    Student student;
    @ManyToOne(cascade = CascadeType.ALL)
    @JoinColumn(name = "course_id")
    Course course;
    private Date startDate;
    private Date endDate;
}

This defines the set of cascadable operations that are propagated to the associated entity. The value cascade = ALL is equivalent to cascade = { PERSIST, MERGE, REMOVE, REFRESH, DETACH }. Additional details here.

Now with a Repository you can save Student:

@Repository
public interface StudentRepository extends JpaRepository<Student, Integer> {
}

Once you have an instance of StudentRepository you can call studentRepository.save(student) (https://docs.spring.io/spring-data/commons/docs/current/api/org/springframework/data/repository/CrudRepository.html?is-external=true#save-S-).

CodePudding user response:

Be careful to use cascade in the @OneToMany annotations in your case. I suggest not to use it and follow these steps to persist them.

  1. Persist the Student and Course instance respectively.(I suggest use ManyToOne in the joint entity only).
  2. Set up the relation between Student and Course in a new StudentCourse(maybe use the name CourseRegistration is better) instance and persist it. NOTE, the student and course instance should be the persisted instance in the first step.

You can wrap the above steps in a transaction scope.

// dummy codes.
@Service 
@Transactional
class SomeService {

    public void saveCourseWithStudents(){
      var savedCourse = courseRepository.save(course);
      var savedStudent = studentRepository.save(student);
    
      studentCourse.setCourse(savedCourse );
      studentCourse.setStudent(savedStudent );

      studentCourseRepsoitory.save(studentCourse);
    }

}

  • Related