首页 > 解决方案 > SpringBoot + Hibernate JPA Lazy fetching 模式仍然查询实体中的列表

问题描述

我正在使用 springboot 和 JPA 做一个 REST API。我试图在一对多关系中懒惰地获取实体。老师上课。我可以看到 JPA 完成的 sql 语句,因为我有调试选项。

在控制器中,调用路径时一切正常,但我可以看到 JPA 正在执行两个查询。一个给老师,另一个给它的课程。据我所知,延迟加载在需要数据并且我不需要它之前不会查询。

我已经检查并确认在控制器中,当我检索教师数据时,JPA 不会查询课程,但在控制器的返回语句之后,某处需要课程,并且当我调用教师信息时它会加载所有内容带有 GET 电话的邮递员。

似乎 LAZY 加载工作正常,但在控制器 JPA 加载课程列表之后。如果我执行 EAGER 获取所有内容,则在 return statemnt 之前加载。

我没有写任何代码,因为我猜这个问题是理论上的而不是实际的。

有谁知道这是如何工作的?

非常感谢!!!!

编辑:

教师桌

@Entity
@Table(name="profesores")
public class Profesor implements Serializable{

    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    private Long id;

    @Column(name="nombre")
    private String nombre;

    @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    @JoinColumn(name = "profesor_id", referencedColumnName = "id")
    private List<Curso> cursos = new ArrayList<>();

}

课程表

@Entity
@Table(name = "curso")
public class Curso implements Serializable {

    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    private Long curso_id;

    private String nombre;

    @Column(name="profesor_id")
    private Long profesorId;
}

控制器

    @GetMapping("/profesor/{id}")
    public ResponseEntity<?> getProfesor(@PathVariable(value = "id") Long id){
        Profesor p = profesorService.findById(id);
        if(p!=null) {
            ResponseEntity<?> re = new ResponseEntity<>(p, HttpStatus.OK);
            //Just one query executed. I don't know the courses yet
            return re;
        }
        else {
            return new ResponseEntity<Void>(HttpStatus.NOT_FOUND);
        }
    }

返回后重新;声明,在某处,课程被检索并 JPA 查询它们。我不知道控制器叫什么,就像我直接从 PostMan 做的那样。

标签: javahibernatespring-bootspring-data-jpalazy-loading

解决方案


Profesor当序列化程序尝试访问序列化的响应时,返回的实体被序列化courses以进行响应之后,JPA 也会加载courses。要解决此问题,您可以为响应创建一个响应类(无courses字段)

public class ProfesorResponse {
    private Long id;
    private String number;
    ...constructor
}

然后将您的实体映射到响应对象中并返回它。

Profesor p = profesorService.findById(id);
ProfesorResponse response = new ProfesorResponse(p.getId(), p.getNumber());

推荐阅读