Eu tenho uma relação entre três objetos de modelo em meu projeto (trechos de modelo e repositório no final do post.
Quando eu ligo, PlaceRepository.findById
ele dispara três consultas selecionadas:
("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
Esse é um comportamento bastante incomum (para mim). Pelo que eu posso dizer depois de ler a documentação do Hibernate, ele sempre deve usar consultas JOIN. Não há diferença nas consultas quando FetchType.LAZY
alteradas para FetchType.EAGER
na Place
classe (consulta com SELECT adicional), o mesmo para a City
classe quando FetchType.LAZY
alterado para FetchType.EAGER
(consulta com JOIN).
Quando eu uso a CityRepository.findById
supressão de disparos, duas seleções:
SELECT * FROM city c where id = arg
SELECT * FROM state s where id = city.state.id
Meu objetivo é ter um comportamento igual em todas as situações (embora seja sempre JOIN ou SELECT, JOIN preferencial).
Definições de modelo:
Lugar, colocar:
@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
}
Cidade:
@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
}
Repositórios:
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);
}