Я пытаюсь использовать граф сущностей с некоторыми данными, и я сталкиваюсь с n + 1 запросом
Я создал новый проект с весенней загрузкой 2.2.6 с некоторыми таблицами.
Как я понял, использование Fetch или Entity Graph должно генерировать только один запрос
@Setter
@Getter
@Entity
@NoArgsConstructor
public class Student {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String firstName;
private String lastName;
private String address;
private LocalDate dateOfBirth;
@ManyToOne(fetch = FetchType.LAZY, optional = false, cascade = CascadeType.ALL)
private Level level;
@ManyToOne(fetch = FetchType.LAZY, optional = false, cascade = CascadeType.ALL)
private Department department;
@ManyToMany(cascade = CascadeType.ALL)
private Set<Formations> formations = new HashSet<>();
@Override
public String toString() {
return "Student{" +
"id=" + id +
", firstName='" + firstName + '\'' +
", lastName='" + lastName + '\'' +
", address='" + address + '\'' +
", dateOfBirth=" + dateOfBirth +
", level=" + level +
", formations=" + formations +
'}';
}
Сущность образований
@Entity
@Data
@NoArgsConstructor
@ToString(exclude = "students")
public class Formations {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String name;
@ManyToMany(mappedBy = "formations")
@JsonIgnore
private Set<Student> students = new HashSet<>();
public Formations(String name) {
this.name = name;
}
}
Репозиторий учащихся
@Repository
public interface StudentRepository extends JpaRepository<Student, Long>,
CustomStudentRepository {
@Query("SELECT s FROM Student s " +
" join fetch s.level l " +
" join fetch s.department d " +
" join fetch s.formations f " +
" where s.id =:id ")
Student fetchWithFormations(@Param("id") Long id);}
Реализация моего пользовательского репозитория
public class StudentRepositoryImpl implements CustomStudentRepository {
@PersistenceContext
private EntityManager em;
private static final String QUERY = " SELECT s FROM Student s join fetch s.formations where s.id =:id ";
public Student findStudentByEntityGraph(Long id) {
EntityGraph<Student> graph = this.em.createEntityGraph(Student.class);
graph.addAttributeNodes("department", "level", "formations");
return em.createQuery(QUERY, Student.class)
.setParameter("id", id)
.setHint("javax.persistence.loadgraph", graph)
.getSingleResult();
}
public Student findStudentByFetch(Long id) {
return em.createQuery(QUERY, Student.class).setParameter("id", id).getSingleResult();
}
}
findStudentByFetch и findStudentByEntityGraph генерируют 04 запроса
// Generated Queries, I have 1 student with id 15 associated with 03 formations
Hibernate: select student0_.id as id1_3_0_, formations2_.id as id1_1_1_, department3_.id as id1_0_2_, level4_.id as id1_2_3_, student0_.address as address2_3_0_, student0_.date_of_birth as date_of_3_3_0_, student0_.department as departme6_3_0_, student0_.first_name as first_na4_3_0_, student0_.last_name as last_nam5_3_0_, student0_.level as level7_3_0_, formations2_.name as name2_1_1_, formations1_.students as students1_4_0__, formations1_.formations as formatio2_4_0__, department3_.name as name2_0_2_, level4_.name as name2_2_3_ from student student0_ inner join student_formations formations1_ on student0_.id=formations1_.students inner join formations formations2_ on formations1_.formations=formations2_.id left outer join department department3_ on student0_.department=department3_.id left outer join level level4_ on student0_.level=level4_.id where student0_.id=?
Hibernate: select students0_.formations as formatio2_4_0_, students0_.students as students1_4_0_, student1_.id as id1_3_1_, student1_.address as address2_3_1_, student1_.date_of_birth as date_of_3_3_1_, student1_.department as departme6_3_1_, student1_.first_name as first_na4_3_1_, student1_.last_name as last_nam5_3_1_, student1_.level as level7_3_1_ from student_formations students0_ inner join student student1_ on students0_.students=student1_.id where students0_.formations=?
Hibernate: select students0_.formations as formatio2_4_0_, students0_.students as students1_4_0_, student1_.id as id1_3_1_, student1_.address as address2_3_1_, student1_.date_of_birth as date_of_3_3_1_, student1_.department as departme6_3_1_, student1_.first_name as first_na4_3_1_, student1_.last_name as last_nam5_3_1_, student1_.level as level7_3_1_ from student_formations students0_ inner join student student1_ on students0_.students=student1_.id where students0_.formations=?
Hibernate: select students0_.formations as formatio2_4_0_, students0_.students as students1_4_0_, student1_.id as id1_3_1_, student1_.address as address2_3_1_, student1_.date_of_birth as date_of_3_3_1_, student1_.department as departme6_3_1_, student1_.first_name as first_na4_3_1_, student1_.last_name as last_nam5_3_1_, student1_.level as level7_3_1_ from student_formations students0_ inner join student student1_ on students0_.students=student1_.id where students0_.formations=?
Если я удаляю формирования из addAttributeNodes и из Query, он генерирует один запрос, как ожидается
Нужна помощь, пожалуйста