'Spring one Controller for nested entities

I'm working on a school project and I'm not sure how to implement this case. I would like to implement it as best practice.

Right now I have 3 entities -> Students, Subjects and StudentSubjects. For all of these enteties I have also a Service. So simplify my entites I creates for each a DTO without any relation to nested Enteties (no Lists).

enter image description here

For the Students-Entity I have created a Controller "StudentController" for simple CRUD. The use-case is that if I get a POST-Request to create a new Student. After the Insert into the Students-Table every Subject with is_default = true should automatically added into the table "StudentSubjects" and this values should be returned.

My question is if it's best practice to return the "StudentSubject"-Values from the POST-Endpoint which creates the Student or should I call a separate endpoint from the backend or should I just return the created Student-Object and the frontend has to call a separate endpoint to get the values of "StudentSubjects"?

StudentDTO

public class StudentDTO {
    private int studentId;
    private String name;

    public StudentDTO() {

    }

    public Students buildStudent() {
        Students student = new Students();
        //Mapping

        return student;
    }
    
    //Getter + Setter
}

SubjectDTO

public class SubjectDTO {
    private int subjectId;
    private String name;
    private boolean isDefault;

    public SubjectDTO() {

    }

    public Subjects buildSubject() {
        Subjects subject = new Subjects();
        //Mapping

        return subject;
    }
    
    //Getter + Setter
}

StudentSubjectDTO

public class StudentSubjectDTO {
    private int stuSubId;
    private StudentDTO student;
    private SubjectDTO subject;

    public StudentSubjectDTO() {

    }

    public StudentSubjects buildStudentSubject() {
        StudentSubjects studentSubject = new StudentSubjects();
        //Mapping

        return studentSubject;
    }
    
    //Getter + Setter
}

StudentController

@RestController
public class StudentController {

    @Autowired
    private StudentService studentService;

    @PostMapping(value = "/student")
    @ResponseBody
    public StudentDTO createStudent(@RequestBody StudentDTO studentDTO) {
        Students student = studentDTO.buildStudent();
        studentService.createStudent(student);

        studentDTO = new StudentDTO(student);
        
        // Should I return StudentSubjectDTO instead of StudentDTO

        return studentDTO;
    }
}


Solution 1:[1]

Even though you have a student-subject table, it does not mean that you have meaning full values straight from that table. This middle table is mostly used for Many-to-Many relationship. But this can be also used for Unidirectional one to many relationships, where the ending entity does not need to know who are referencing it. For example User and Role relationship. In JPA we use one user can have many roles. But roles do not need to know who are using them as a role. So that is Uni directional Many-to-One. So I suggest something like this:

@OneToMany(fetch = FetchType.EAGER,cascade = CascadeType.PERSIST)
@JoinTable(
        name = "user_role",
        joinColumns = @JoinColumn(
                name = "user_id",
                referencedColumnName = "id"
        ),
        inverseJoinColumns = @JoinColumn(
                name = "role_id",
                referencedColumnName = "id"
        ))
private List<Role> roles;

Solution 2:[2]

Unless there is specific requirement, if /student service is used to create student then you can generally just return details of student ; even though createStudent is creating mapping for Student-Subject. This way your web service contract will look little bit clean & clear i.e. inserting student & returning details of it.

You can add another @GetMapping service in same @RestController with parameters(e.g. student id,student name ) of Student for fetching Student subject details. Any one calling this new service either need to know Student id or name details.

If your design require minimal approach then you can still return Student-subject in same /student service.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Juliyanage Silva
Solution 2 Ashish Patil