【发布时间】:2021-05-17 16:00:21
【问题描述】:
我们有一个课程实体,每个课程都有参加课程的学生和嘉宾名单:
public class Lesson {
@Id
private Long id;
// ...other properties
@OneToMany(mappedBy = "lesson", cascade = CascadeType.ALL)
private List<Student> students;
@OneToMany(mappedBy = "lesson", , cascade = CascadeType.ALL)
private List<Guest> guests;
// ...constructors, getters and setters
}
// --------------------------------------------------------------------------------------------
public class Student {
@Id
private Long id;
// ...
@ManyToOne
@JoinColumn(name = "lesson_id")
private Lesson lesson;
// ...
}
// -------------------------------------------------------------------------------------------
public class Guest {
@Id
private Long id;
// ...
@ManyToOne
@JoinColumn(name = "lesson_id")
private Lesson lesson;
// ...
}
我想获取学生和客人的所有课程,因此我使用标准 API 构建了以下查询:
@Repository
public class LessonCriteriaRepositoryImpl implements LessonCriteriaRepository {
@PersistenceContext
private EntityManager em;
@Override
public List<Lesson> findAll() {
CriteriaBuilder builder = em.getCriteriaBuilder();
CriteriaQuery<Lesson> criteriaQuery = builder.createQuery(Lesson.class);
Root<Lesson> lesson = criteriaQuery.from(Lesson.class);
lesson.fetch(Lesson_.students, JoinType.LEFT);
lesson.fetch(Lesson_.guests, JoinType.LEFT);
criteriaQuery.select(lesson).distinct(true);
TypedQuery<Lesson> query = em.createQuery(criteriaQuery);
return query.getResultList();
}
}
我得到 MultipleBagFetchException 因为我不能一次获取多个集合。根据 Vlad Mihalcea (https://twitter.com/vlad_mihalcea) 帖子 (Hibernate throws MultipleBagFetchException - cannot simultaneously fetch multiple bags) 的说法,击败 MultipleBagFetchException 的正确方法是进行两个单独的查询并一个接一个地获取集合。
但我不明白如何使用条件 API 构建这样两个查询一个接一个地获取集合。 (我需要使用条件 API,因为我在这里给出了一些非常简化的代码作为示例,在实际应用中我有复杂的过滤器并且我使用许多谓词来构建查询)。
【问题讨论】:
标签: java hibernate jpa criteria-api