首页 > 解决方案 > 在 FetchType.EAGER 通过 EntityGraph 和 Specification 查询

问题描述

我正在为一个实体制作图表:

@Entity
@Table(name = "teacher")
@NamedEntityGraph(name = "entity-graph",
        attributeNodes = {@NamedAttributeNode(value = "classRoom",subgraph = "teacher-subgraph")},
        subgraphs = {
        @NamedSubgraph(name = "teacher-subgraph",attributeNodes = {
                @NamedAttributeNode("teacher")})})
public final class Teacher extends BaseModel {

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "teacher_id")
    @Setter
    @Getter
    private ClassRoom classRoom;

实体教室:

@Entity
@Table(name = "class_room")
public final class ClassRoom extends BaseModel {

    @OneToMany(mappedBy = "classRoom", fetch = FetchType.EAGER)
    @Getter
    @Setter
    private Set<Teacher> teacher = new HashSet<>();

    @OneToMany(mappedBy = "classRoom",fetch = FetchType.EAGER)
    @Getter
    @Setter
    private Set<Pupil> pupil = new HashSet<>();

我通过规范创建一个请求:

public class TeacherSpecification {
    public static Specification<Teacher> findBy(String name) {
        return new Specification<Teacher>() {
            @Override
            public Predicate toPredicate(Root<Teacher> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
                root = criteriaQuery.from(Teacher.class);
                criteriaQuery.distinct(true);
                Join<Teacher, ClassRoom> teacherClassRoomJoin = root.join("classRoom");
                return criteriaBuilder.equal(teacherClassRoomJoin.get(Teacher_.NAME),name);

            }
        };
    }

在 TeacherRepository 中绘制图表:

public interface TeacherRepository extends CrudRepository<Teacher,Long>, JpaSpecificationExecutor<Teacher> {
    List<Teacher> findByName(String name);

    @EntityGraph(value = "entity-graph")
    List<Teacher> findAll(Specification specification);

}

测试查询:

@Test
public void testFinal() {
    Iterable<Teacher> findByFinal = teacherRepository.findAll(TeacherSpecification.findBy("Alla"));
    findByFinal.forEach(c-> System.out.println(c.getClassRoom().getId() + " " + c.getClassRoom().getName()));
    findByFinal.forEach(t-> System.out.println(t.getId() + " " + t.getSurname() + " " + t.getDiscipline()));
}

我在控制台中收到错误:

org.springframework.dao.InvalidDataAccessApiUsageException: org.hibernate.QueryException: 查询指定连接提取,但提取关联的所有者不在选择列表中

请求任务让老师让 ClassRoom 加载 EAGER。我在哪里做错了?

标签: javaspringhibernatespring-data-jpa

解决方案


推荐阅读