Commit 765ec472 authored by Filip Filchev's avatar Filip Filchev
Browse files

Fix ManyToMany Realation Courses-Students and OneToMany Teacher-Courses

Add Annotations in Course, Student and Teacher for the Relations
Add Methods in CourseRepository that find a Course and fill the Students and Teacher from Foreign Keys
Add Fix findById and findAll in CourseService accordingly to the new Methods in CourseRepository
parent 453065a8
Showing with 99 additions and 40 deletions
+99 -40
......@@ -31,12 +31,12 @@ public class DefaultAdministratorService implements AdministratorService {
}
@Override
public StudentCourseResponse enroll(StudentCourseIdRequest dto) { //TODO: Fix Many to Many
public StudentCourseResponse enroll(StudentCourseIdRequest dto) {
return findByIdExecuteAndSave(dto, (s, c) -> c.enroll(s));
}
@Override
public StudentCourseResponse dismiss(StudentCourseIdRequest dto) {//TODO: Fix Many to Many
public StudentCourseResponse dismiss(StudentCourseIdRequest dto) {
return findByIdExecuteAndSave(dto, (s, c) -> c.dismiss(s));
}
......@@ -58,8 +58,8 @@ public class DefaultAdministratorService implements AdministratorService {
executor.accept(student, course);
courseService.save(course); //TODO: Fix Many to Many
studentService.save(student); //TODO: Fix Many to Many
courseService.save(course);
studentService.save(student);
return new StudentCourseResponse(student, course);
}
......@@ -72,7 +72,7 @@ public class DefaultAdministratorService implements AdministratorService {
executor.accept(teacher, course);
courseService.save(course);
// teacherService.save(teacher);
teacherService.save(teacher);
return new TeacherCourseResponse(teacher, course);
}
......
......@@ -5,10 +5,14 @@ import org.springframework.stereotype.Service;
import studentmanagement.data.course.CourseRepository;
import studentmanagement.model.course.Course;
import studentmanagement.model.dto.create.CourseCreateRequest;
import studentmanagement.model.key.IDableKey;
import studentmanagement.model.person.teacher.Teacher;
import studentmanagement.service.course.exception.CourseDoesNotExistException;
import studentmanagement.service.generic.DefaultService;
import studentmanagement.service.teacher.TeacherService;
import java.util.Collection;
@Service
public class DefaultCourseService extends DefaultService<Course> implements CourseService {
private final TeacherService teacherService;
......@@ -30,4 +34,15 @@ public class DefaultCourseService extends DefaultService<Course> implements Cour
teacherService.save(teacher);
return save(course);
}
@Override
public Course findById(IDableKey key) {
return ((CourseRepository) repository).findCourseWithStudentsAndTeacherById(key.id())
.orElseThrow(() -> new CourseDoesNotExistException("Course with " + key + " does not exist"));
}
@Override
public Collection<Course> findAll() {
return ((CourseRepository) repository).findAll();
}
}
\ No newline at end of file
package studentmanagement.service.course.exception;
public class CourseDoesNotExistException extends Exception {
public class CourseDoesNotExistException extends RuntimeException {
public CourseDoesNotExistException(String message) {
super(message);
}
......
......@@ -5,6 +5,7 @@ import org.springframework.stereotype.Service;
import studentmanagement.data.grade.GradeRepository;
import studentmanagement.model.course.Course;
import studentmanagement.model.course.dto.CourseStudentListResponse;
import studentmanagement.model.course.exception.StudentNotInCourseException;
import studentmanagement.model.dto.create.AddGradeRequest;
import studentmanagement.model.dto.create.StudentCourseIdRequest;
import studentmanagement.model.grade.Grade;
......@@ -107,6 +108,11 @@ public class DefaultGradeService implements GradeService {
Student student = studentService.findById(dto.studentKey());
Course course = courseService.findById(dto.courseKey());
if (!course.isEnrolled(student)) {
throw new StudentNotInCourseException(
"Student with ID:" + student.getId() + " is not enrolled in this Course");
}
Grade toAdd = new Grade(student, course, grade);
save(toAdd);
......@@ -144,7 +150,10 @@ public class DefaultGradeService implements GradeService {
@Override
public Double findAverageForStudentInCourse(StudentCourseIdRequest dto) {
return null;
Collection<Grade> grades =
gradeRepository.findAllByStudentIdAndCourseId(dto.studentKey().id(), dto.courseKey().id());
return average(grades);
}
@Override
......
......@@ -10,8 +10,6 @@ import studentmanagement.model.key.IDableKey;
import java.util.Collection;
public interface GradeService {
// StudentCourseResponse add(StudentCourseIdRequest dto);
Grade save(Grade grade);
Collection<Grade> saveAll(Collection<Grade> grades);
......
package studentmanagement.data.course;
import org.springframework.data.jpa.repository.EntityGraph;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import studentmanagement.model.course.Course;
import java.util.List;
import java.util.Optional;
@Repository
public interface CourseRepository extends JpaRepository<Course, Long> {
@EntityGraph(attributePaths = {"students", "teacher"})
Optional<Course> findCourseWithStudentsAndTeacherById(Long id);
@EntityGraph(attributePaths = {"students", "teacher"})
List<Course> findAll();
}
......@@ -6,5 +6,4 @@ import studentmanagement.model.person.student.Student;
@Repository
public interface StudentRepository extends JpaRepository<Student, Long> {
}
\ No newline at end of file
......@@ -10,6 +10,7 @@ import jakarta.persistence.MappedSuperclass;
public class DefaultIDable implements IDable {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(nullable = false)
private Long id;
@Column
......@@ -23,15 +24,15 @@ public class DefaultIDable implements IDable {
this.name = name;
}
public void setId(Long id) {
this.id = id;
}
@Override
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
@Override
public String getName() {
return name;
......
package studentmanagement.model.course;
import jakarta.persistence.CascadeType;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.FetchType;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.JoinTable;
import jakarta.persistence.ManyToMany;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.Table;
import org.hibernate.Hibernate;
import studentmanagement.model.DefaultIDable;
import studentmanagement.model.course.exception.StudentAlreadyInCourseException;
import studentmanagement.model.course.exception.StudentNotInCourseException;
......@@ -24,23 +29,20 @@ public class Course extends DefaultIDable implements Comparable<Course> {
@Column
private long totalHours;
//TODO Fix Many to Many
// @ManyToMany(fetch = FetchType.LAZY,
// cascade = {
// CascadeType.PERSIST,
// CascadeType.MERGE
// })
// @JoinTable(name = "course_students",
// joinColumns = {@JoinColumn(name = "course_id")},
// inverseJoinColumns = {@JoinColumn(name = "student_id")})
@ManyToMany
private Set<Student> students;
@ManyToOne
@ManyToMany(fetch = FetchType.LAZY,
cascade = {
CascadeType.PERSIST,
CascadeType.MERGE
})
@JoinTable(name = "course_students",
joinColumns = {@JoinColumn(name = "course_id", referencedColumnName = "id")},
inverseJoinColumns = {@JoinColumn(name = "student_id", referencedColumnName = "id")})
private Set<Student> students = new HashSet<>();
@ManyToOne(fetch = FetchType.LAZY)
private Teacher teacher;
public Course() {
students = new HashSet<>();
}
public Course(String name, long totalHours, Teacher teacher) {
......@@ -68,6 +70,10 @@ public class Course extends DefaultIDable implements Comparable<Course> {
public void employ(Teacher teacher) {
this.teacher = teacher;
if (Hibernate.isInitialized(teacher.getCourses())) {
teacher.getCourses().add(this);
}
}
public void fire(Teacher teacher) throws TeacherNotInCourseException {
......@@ -75,6 +81,10 @@ public class Course extends DefaultIDable implements Comparable<Course> {
throw new TeacherNotInCourseException("Teacher: " + teacher + " is no employed in this Course");
}
this.teacher = null;
if (Hibernate.isInitialized(teacher.getCourses())) {
teacher.getCourses().remove(this);
}
}
/**
......@@ -84,12 +94,12 @@ public class Course extends DefaultIDable implements Comparable<Course> {
* @throws StudentAlreadyInCourseException - if the Student is already in the Course
*/
public Student enroll(Student student) {
if (students.isEmpty()) {
students = new HashSet<>();
}
students.add(student);
if (Hibernate.isInitialized(student.getCourses())) {
student.getCourses().add(this);
}
return student;
}
......@@ -98,6 +108,10 @@ public class Course extends DefaultIDable implements Comparable<Course> {
students.remove(student);
if (Hibernate.isInitialized(student.getCourses())) {
student.getCourses().add(this);
}
return student;
}
......
......@@ -2,21 +2,20 @@ package studentmanagement.model.person.student;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.ManyToMany;
import jakarta.persistence.Table;
import studentmanagement.model.course.Course;
import studentmanagement.model.person.Person;
import java.util.HashSet;
import java.util.Set;
@Entity
@Table(name = "Students")
public class Student extends Person {
//TODO Fix Many to Many
// @ManyToMany(fetch = FetchType.LAZY,
// cascade = {
// CascadeType.PERSIST,
// CascadeType.MERGE
// },
// mappedBy = "students")
// private Set<Course> courses;
@ManyToMany(mappedBy = "students")
private transient Set<Course> courses = new HashSet<>();
@Column
private long age;
......@@ -29,6 +28,10 @@ public class Student extends Person {
this.age = age;
}
public Set<Course> getCourses() {
return courses;
}
public long getAge() {
return age;
}
......
......@@ -2,15 +2,23 @@ package studentmanagement.model.person.teacher;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.OneToMany;
import jakarta.persistence.Table;
import studentmanagement.model.course.Course;
import studentmanagement.model.person.Person;
import java.util.HashSet;
import java.util.Set;
@Entity
@Table(name = "Teachers")
public class Teacher extends Person {
@Column
private Degree degree;
@OneToMany(mappedBy = "teacher")
private transient Set<Course> courses = new HashSet<>();
public Teacher() {
}
......@@ -20,6 +28,10 @@ public class Teacher extends Person {
this.degree = degree;
}
public Set<Course> getCourses() {
return courses;
}
public Degree getDegree() {
return degree;
}
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment