Я разрабатываю приложение, используя Spring Boot, Spring Data и Hibernate.У меня есть сущность «Клиент», которая имеет отношение «онтомания» с другой сущностью «Резервирование» следующим образом:
@Entity
public class Client implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@OneToMany( mappedBy = "client", fetch=FetchType.EAGER)
@Fetch(value = FetchMode.JOIN)
private Set<Reservation> reservations = new HashSet<>();
}
Я реализовал интерфейс JpaRepository, чтобы я мог манипулировать данными клиента:
public interface ClientRepository extends JpaRepository<Client, Long> {}
В классе обслуживания я реализовал метод поиска всех клиентов в моей базе данных:
@Service
public class ClientService {
@Autowired
private ClientRepository clientRepository;
@Transactional(readOnly = true)
public List<Client> findAll() {
return clientRepository.findAll();
}}
Выполнение findAll () работает хорошо и возвращает всех клиентов и их резервирование.Тем не менее, в моем журнале sql у меня есть N + 1 запросов, которые были выполнены (N количество клиентов), хотя я установил fetch=FetchType.EAGER
в моем объекте Client.Я думал, что hibernate создаст один запрос, в котором он объединит все необходимые данные для получения клиентов и их повторных запросов.
Итак, я вынужден явно присоединиться к клиенту и выполнить резервирование с помощью запроса:
@Query("select client from Client client left join fetch client.reservations")
public List<Client> findAllEager();
Я также нашел другую альтернативу, которая позволяет выполнять только два запроса для извлечения всех клиентов и их резервирований:
@OneToMany(mappedBy = "client", fetch = FetchType.EAGER)
@Fetch(value = FetchMode.SUBSELECT)
Я отмечаю, что из этого обсуждения JPA eager fetch не присоединяется, похоже, что @OneToMany(fetch=FetchType.EAGER) @Fetch(value = FetchMode.JOIN)
выполнит только один запрос для получения результата, который не является моим случаем.
Выполняет ли OneToMany(fetch=FetchType.EAGER)
N + 1 запрос для извлечения данных?