SpringBoot + Hibernate JPA Режим отложенной выборки по-прежнему запрашивает списки в сущности - PullRequest
0 голосов
/ 02 апреля 2020

Я делаю REST API с использованием Springboot и JPA. Я пытаюсь лениво выбрать сущность в отношениях Один ко Многим. Преподаватель курсов. Я вижу операторы sql, сделанные JPA, так как у меня включена опция отладки.

В контроллере при вызове пути все прекрасно работает, но я вижу, что JPA выполняет два запроса. Один для учителя, а другой для его курсов. Как я знаю, отложенная загрузка не запрашивает, пока данные не требуются, а я не требую их.

Я проверил и подтвердил, что в контроллере, когда я получаю данные учителя, JPA не запрашивает курсы, но ПОСЛЕ оператора возврата контроллера, где-то, курсы требуются, и он загружает все, когда я вызываю информацию учителя от почтальона с вызовом GET.

Кажется, что загрузка LAZY работает правильно , но после контроллера JPA загружает список курсов. Если я выполняю EAGER-загрузку, все загружается до возврата 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);
        }
    }

После возврата re; Скажите, где-то, курсы извлекаются и JPA запрашивает их. Я не знаю, что вызывает контроллер, как я делаю это непосредственно из PostMan.

1 Ответ

1 голос
/ 02 апреля 2020

После того, как возвращенный объект 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());
...