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 = 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
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.LAZYmodifiées en FetchType.EAGERdans la Placeclasse (requête avec SELECT supplémentaire), de même pour la Cityclasse lorsqu'elle est FetchType.LAZYmodifiée en FetchType.EAGER(requête avec JOIN).
Lorsque j'utilise la CityRepository.findByIdsuppression des incendies, deux sélections:
SELECT * FROM city c where id = argSELECT * 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);
}