Mam relację między trzema obiektami modelu w moim projekcie (fragmenty modelu i repozytorium na końcu postu.
Kiedy dzwonię PlaceRepository.findById
, uruchamia trzy zapytania wybierające:
(„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
To dość niezwykłe zachowanie (dla mnie). O ile wiem po przeczytaniu dokumentacji Hibernate'a, powinien on zawsze używać zapytań JOIN. Nie ma różnicy w zapytaniach po FetchType.LAZY
zmianie na FetchType.EAGER
w Place
klasie (zapytanie z dodatkowym SELECT), to samo dla City
klasy po FetchType.LAZY
zmianie na FetchType.EAGER
(zapytanie z JOIN).
Kiedy używam CityRepository.findById
tłumienia pożarów, dwie opcje:
SELECT * FROM city c where id = arg
SELECT * FROM state s where id = city.state.id
Moim celem jest zachowanie takiego samego zachowania we wszystkich sytuacjach (zawsze JOIN lub SELECT, preferowane JOIN).
Definicje modeli:
Miejsce:
@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
}
Miasto:
@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
}
Repozytoria:
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);
}
MiastoRepozytorium:
public interface CityRepository extends JpaRepository<City, Long>, CityRepositoryCustom {
City findById(int id);
}