У меня есть отношение между тремя объектами модели в моем проекте (фрагменты модели и репозитория в конце сообщения.
Когда я вызываю PlaceRepository.findById
, он запускает три запроса:
( "SQL" )
-
SELECT * FROM place p where id = arg
-
SELECT * FROM user u where u.id = place.user.id
-
SELECT * FROM city c LEFT OUTER JOIN state s on c.woj_id = s.id where c.id = place.city.id
Это довольно необычное поведение (для меня). Насколько я могу судить по чтению документации Hibernate, он всегда должен использовать JOIN-запросы. Нет разницы в запросах, когда FetchType.LAZY
изменен на FetchType.EAGER
в классе Place
(запрос с дополнительным SELECT), тот же для класса City
, когда FetchType.LAZY
изменен на FetchType.EAGER
(запрос с JOIN).
Когда я использую CityRepository.findById
подавление пожаров, два выбирают:
-
SELECT * FROM city c where id = arg
-
SELECT * FROM state s where id = city.state.id
Моя цель - иметь поведение sam во всех ситуациях (либо всегда JOIN, либо SELECT, JOIN предпочтительнее).
Определения модели:
Место:
@Entity
@Table(name = "place")
public class Place extends Identified {
@Fetch(FetchMode.JOIN)
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "id_user_author")
private User author;
@Fetch(FetchMode.JOIN)
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "area_city_id")
private City city;
//getters and setters
}
Город:
@Entity
@Table(name = "area_city")
public class City extends Identified {
@Fetch(FetchMode.JOIN)
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "area_woj_id")
private State state;
//getters and setters
}
Хранилища:
PlaceRepository
public interface PlaceRepository extends JpaRepository<Place, Long>, PlaceRepositoryCustom {
Place findById(int id);
}
UserRepository:
public interface UserRepository extends JpaRepository<User, Long> {
List<User> findAll();
User findById(int id);
}
CityRepository:
public interface CityRepository extends JpaRepository<City, Long>, CityRepositoryCustom {
City findById(int id);
}