Tengo una relación entre tres objetos modelo en mi proyecto (fragmentos de modelo y repositorio al final de la publicación.
Cuando lo llamo PlaceRepository.findById, activa tres consultas seleccionadas:
("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
Ese es un comportamiento bastante inusual (para mí). Por lo que puedo decir, después de leer la documentación de Hibernate, siempre debería usar consultas JOIN. No hay diferencia en las consultas cuando se FetchType.LAZYcambia a FetchType.EAGERen la Placeclase (consulta con SELECT adicional), lo mismo para la Cityclase cuando se FetchType.LAZYcambia a FetchType.EAGER(consulta con JOIN).
Cuando uso la CityRepository.findByIdsupresión de incendios dos selecciones:
SELECT * FROM city c where id = argSELECT * FROM state s where id = city.state.id
Mi objetivo es tener un comportamiento similar al sam en todas las situaciones (ya sea siempre JOIN o SELECT, aunque se prefiere JOIN).
Definiciones de modelo:
Sitio:
@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
}
Ciudad:
@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
}
Repositorios:
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);
}