Spring Boot + Hibernate JPA Lazy fetching 模式仍然查询实体中的列表
SpringBoot + Hibernate JPA Lazy fetching mode still queries lists in an entity
我正在使用 springboot 和 JPA 进行 REST API。
我正在尝试懒惰地获取一对多关系中的实体。授课老师。
我可以看到 JPA 完成的 sql 语句,因为我打开了调试选项。
在控制器中,调用路径时一切正常,但我可以看到 JPA 正在执行两个查询。一个给老师,另一个给它的课程。据我所知,延迟加载在需要数据之前不会查询,而我不需要它。
我已经检查并确认在控制器中,当我检索教师数据时,JPA 不查询课程,但是在控制器的 return 声明之后,某处需要课程并且它当我通过 GET 调用邮递员的教师信息时加载所有内容。
似乎 LAZY 加载工作正常,但在控制器 JPA 加载课程列表之后。如果我做 EAGER 获取所有内容都在 return statemnt.
之前加载
我没有写任何代码,因为我猜这个问题的理论性大于实际性。
有人知道这是怎么回事吗?
非常感谢!!!
编辑:
老师table
@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<>();
}
课程Table
@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);
}
}
后return重新;声明,在某处,课程被检索并且 JPA 查询它们。不知道controller调用的是什么,我是直接从PostMan调用的
在 returned 实体 Profesor
被序列化以响应时,当序列化器尝试访问 courses
以序列化响应然后 JPA 加载 courses
时。要解决此问题,您可以为响应创建一个响应 class(没有 courses
字段)
public class ProfesorResponse {
private Long id;
private String number;
...constructor
}
然后将您的实体映射到响应对象中并return它。
Profesor p = profesorService.findById(id);
ProfesorResponse response = new ProfesorResponse(p.getId(), p.getNumber());
我正在使用 springboot 和 JPA 进行 REST API。 我正在尝试懒惰地获取一对多关系中的实体。授课老师。 我可以看到 JPA 完成的 sql 语句,因为我打开了调试选项。
在控制器中,调用路径时一切正常,但我可以看到 JPA 正在执行两个查询。一个给老师,另一个给它的课程。据我所知,延迟加载在需要数据之前不会查询,而我不需要它。
我已经检查并确认在控制器中,当我检索教师数据时,JPA 不查询课程,但是在控制器的 return 声明之后,某处需要课程并且它当我通过 GET 调用邮递员的教师信息时加载所有内容。
似乎 LAZY 加载工作正常,但在控制器 JPA 加载课程列表之后。如果我做 EAGER 获取所有内容都在 return statemnt.
之前加载我没有写任何代码,因为我猜这个问题的理论性大于实际性。
有人知道这是怎么回事吗?
非常感谢!!!
编辑:
老师table
@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<>();
}
课程Table
@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);
}
}
后return重新;声明,在某处,课程被检索并且 JPA 查询它们。不知道controller调用的是什么,我是直接从PostMan调用的
在 returned 实体 Profesor
被序列化以响应时,当序列化器尝试访问 courses
以序列化响应然后 JPA 加载 courses
时。要解决此问题,您可以为响应创建一个响应 class(没有 courses
字段)
public class ProfesorResponse {
private Long id;
private String number;
...constructor
}
然后将您的实体映射到响应对象中并return它。
Profesor p = profesorService.findById(id);
ProfesorResponse response = new ProfesorResponse(p.getId(), p.getNumber());