Отфильтруйте одну сторону по отношению «многие ко многим»

#java #sql #spring #jpa #many-to-many

Вопрос:

Я учусь использовать JPA и сталкиваюсь с проблемой :

У меня есть эта схема в моей базе данных, где студенты могут подавать заявки на несколько курсов, и каждое устройство может быть оценено несколько раз. введите описание изображения здесь

Я использовал JPA для создания ассоциации

  @Entity @Table(name = "student") @AllArgsConstructor @NoArgsConstructor @ToString @Getter @Setter public class Student {  @Id  @JsonProperty(access = JsonProperty.Access.READ_ONLY)  @GeneratedValue(strategy = GenerationType.IDENTITY)  private Long id;   private String name;   @Column(name="family_name")  private String familyName;   @OneToMany(mappedBy = "student", fetch = FetchType.LAZY)  @JsonManagedReference  @JsonProperty(access = JsonProperty.Access.READ_ONLY)  private Setlt;CourseFollowgt; followedCourses; }  
 @Entity @Table(name = "course_follow") @Getter @Setter public class CourseFollow {   @Id  @GeneratedValue  private Long id;   @ManyToOne  @JoinColumn(name = "student_id")  @JsonBackReference  private Student student;   @ManyToOne  @JoinColumn(name = "course_id")  @JsonBackReference  private Course course;   @Column(name = "from_date")  private LocalDate fromDate;   @Column(name = "to_date")  private LocalDate toDate;   @OneToMany(mappedBy = "gradedCourse")  @JsonManagedReference  @JsonProperty(access = JsonProperty.Access.READ_ONLY)  private Setlt;Gradegt; gradings;  }  
   @Entity @Table(name = "course") @AllArgsConstructor @NoArgsConstructor @ToString @Getter @Setter public class Course {  @Id  @JsonProperty(access = JsonProperty.Access.READ_ONLY)  @GeneratedValue(strategy = GenerationType.IDENTITY)  private Long id;   private String name;   @OneToMany(mappedBy = "course")  @JsonManagedReference  @JsonProperty(access = JsonProperty.Access.READ_ONLY)  private Setlt;CourseFollowgt; followings; }   

And the grade is split into two classes since I had to use an EmbeddedId, I’m not sure if that is good pratice but it’s to prevent the use of native queries

  @Entity @Getter @Setter @AllArgsConstructor @NoArgsConstructor @Table(name = "grade") public class Grade {  @JsonProperty(value = "grading")  @EmbeddedId  GradePK grade;   @ManyToOne  @JsonBackReference  @JoinColumn(name="follow_id", nullable=false)  CourseFollow gradedCourse; }  
 @Embeddable @AllArgsConstructor @NoArgsConstructor @ToString @Getter @Setter public class GradePK implements Serializable {  private LocalDate date;  private Double grade; }  

Моя проблема прямо сейчас заключается в том, что я хотел бы собрать всех студентов, у которых средняя оценка была ниже определенной отметки (например, неудача), вернуть этого студента и массив всех случаев, когда они могли потерпеть неудачу, они провалили курс (Массив последующих курсов).

У меня есть пользовательский запрос, который выполняет работу по поиску правильных студентов, которые провалили урок, но он также извлекает ВСЕ пройденные ими курсы (включая тот, который они, возможно, прошли). :

 @Repository @Transactional public interface StudentRepository extends CrudRepositorylt;Student, Longgt; {  @Query(value = "SELECT s FROM Student s WHERE s.id in("    " SELECT c.student.id FROM CourseFollow c"    " JOIN Grade g on g.gradedCourse.id = c.id"    " WHERE c.course.id = :courseId"    " GROUP BY c.student.id"    " HAVING avg(g.grade.grade) lt; :mark"   ")")  Listlt;Studentgt; getStudentByMark(long courseId, double mark); }  

Есть ли способ отфильтровать следующий курс ? Или я должен получить это с помощью службы CourseFollowService ? Если да, то есть ли способ сообщить репозиторию, чтобы он не извлекал данные из ассоциации «многие ко многим», поскольку они будут переопределены неудачными классами, добавленными из другой службы.

Извините за длинный пост, я сейчас как бы борюсь с JPA, и я не мог найти способ сформулировать свою проблему короче !

Комментарии:

1. Когда вы получаете Student объект и вызываете followedCourses отношение, оно всегда получает все последующие курсы. Даже если запрос, используемый для извлечения Student , отфильтровал эти отношения. AFAIK нет способа получить отфильтрованное представление отношения через поле JPA. Вы всегда можете сделать отдельный запрос для каждого студента. Это приводит к проблеме N 1 запросов, но как это повлияет на ваше приложение, зависит от точного использования. Как вы планируете это использовать?