我确实在项目中的三个模型对象之间有关系(文章末尾的模型和存储库片段)。
当我调用PlaceRepository.findById它时,会触发三个选择查询:
PlaceRepository.findById
(“ 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
(对我而言)这是非常不正常的行为。据阅读Hibernate文档后所知,它应该始终使用JOIN查询。在类中FetchType.LAZY更改为 查询时(带有附加SELECT 的查询)没有任何区别,而在类更改为 (使用JOIN查询时)则没有变化。FetchType.EAGER``Place``City``FetchType.LAZY``FetchType.EAGER
FetchType.LAZY
FetchType.EAGER``Place``City``FetchType.LAZY``FetchType.EAGER
当我使用CityRepository.findById抑制射击时,有两个选择:
CityRepository.findById
SELECT * FROM city c where id = arg
SELECT * FROM state s where id = city.state.id
我的目标是在所有情况下都具有sam行为(始终为JOIN或SELECT,但首选JOIN)。
型号定义:
地点:
@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 }
市:
@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 }
仓库:
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); }
城市资料库:
public interface CityRepository extends JpaRepository<City, Long>, CityRepositoryCustom { City findById(int id); }
我认为Spring Data会忽略FetchMode。在使用Spring Data时,我总是使用@NamedEntityGraph和@EntityGraph批注
@NamedEntityGraph
@EntityGraph
@Entity @NamedEntityGraph(name = "GroupInfo.detail", attributeNodes = @NamedAttributeNode("members")) public class GroupInfo { // default fetch mode is lazy. @ManyToMany List<GroupMember> members = new ArrayList<GroupMember>(); … } @Repository public interface GroupRepository extends CrudRepository<GroupInfo, String> { @EntityGraph(value = "GroupInfo.detail", type = EntityGraphType.LOAD) GroupInfo getByGroupName(String name); }
在 此处 查看文档