J'ai une relation entre trois objets de modèle dans mon projet (des extraits de modèle et de référentiel à la fin de l'article.
Quand j'appelle PlaceRepository.findById
il déclenche trois requêtes de sélection:
("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
C'est un comportement plutôt inhabituel (pour moi). Pour autant que je sache après avoir lu la documentation Hibernate, il devrait toujours utiliser les requêtes JOIN. Il n'y a aucune différence dans les requêtes lorsqu'elles sont FetchType.LAZY
modifiées en FetchType.EAGER
dans la Place
classe (requête avec SELECT supplémentaire), de même pour la City
classe lorsqu'elle est FetchType.LAZY
modifiée en FetchType.EAGER
(requête avec JOIN).
Lorsque j'utilise la CityRepository.findById
suppression des incendies, deux sélections:
SELECT * FROM city c where id = arg
SELECT * FROM state s where id = city.state.id
Mon objectif est d'avoir un comportement sam dans toutes les situations (soit toujours JOIN ou SELECT, JOIN préféré cependant).
Définitions du modèle:
Endroit:
@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
}
Ville:
@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
}
Dépôts:
LieuRepository
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);
}