简体   繁体   中英

SpringBoot + Hibernate JPA Lazy fetching mode still queries lists in an entity

I am doing a REST API using springboot and JPA. I am trying to lazy fetching an entity in a One to Many relationship. Teacher to courses. I can see the sql statements done by JPA as I have the debuging option on.

In the controller, when calling a path all works great, but I can see that JPA is executing two queries. One for the teacher and another one for its courses. As I know, the lazy loading does not query until the data is required and I am not requiring it.

I have checked and conirmed that in the controller, when I retrieve the teacher data JPA does not query for the courses, but AFTER the return statement of the controller, somewhere, the courses are required and it loads everything when I call the teacher info from postman with a GET call.

It seems as if the LAZY loading is working correctly, but after the controller JPA loads the course list. If I do the EAGER fetching everything is loaded before the return statemnt.

I am not writing any code as I guess the question is more theorical than practical.

Does anyone know how this works?

Thank you so much!!!!

EDIT:

Teacher 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<>();

}

Course 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;
}

Controller

    @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);
        }
    }

After the return re; statement, somewhere, the courses are retrieved and JPA queries for them. I don't know what does the controller call, as I do directly from PostMan.

After returned Entity Profesor is serialized for response when serializer try to access courses to serialized for response then JPA load courses also. To solve this issue, You can create a response class for response (without courses field)

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

then map your entity in response object and return it.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM