Ich habe eine Beziehung zwischen drei Modellobjekten in meinem Projekt (Modell- und Repository-Snippets am Ende des Beitrags.
Wenn ich anrufe PlaceRepository.findById, werden drei ausgewählte Abfragen ausgelöst:
("sql")
SELECT * FROM place p where id = argSELECT * FROM user u where u.id = place.user.idSELECT * FROM city c LEFT OUTER JOIN state s on c.woj_id = s.id where c.id = place.city.id
Das ist eher ungewöhnliches Verhalten (für mich). Soweit ich nach dem Lesen der Hibernate-Dokumentation feststellen kann, sollten immer JOIN-Abfragen verwendet werden. Es gibt keinen Unterschied zwischen den Abfragen, wenn FetchType.LAZYsie FetchType.EAGERin der PlaceKlasse geändert werden (Abfrage mit zusätzlichem SELECT). Dies gilt auch für die CityKlasse, wenn sie FetchType.LAZYgeändert wird FetchType.EAGER(Abfrage mit JOIN).
Wenn ich die CityRepository.findByIdUnterdrückung von Bränden verwende, werden zwei Optionen ausgewählt:
SELECT * FROM city c where id = argSELECT * FROM state s where id = city.state.id
Mein Ziel ist es, in allen Situationen das gleiche Verhalten zu haben (entweder immer JOIN oder SELECT, JOIN jedoch bevorzugt).
Modelldefinitionen:
Platz:
@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
}
Stadt:
@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
}
Repositories:
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);
}