我正在使用Spring Data和Hibernate 6.x开发一个Sping Boot 3.x应用程序。我有一个实体类,如下所示:
@Entity
public class User {
@Id
private UUID id = UUID.randomUUID();
@Column
private String country;
@ManyToMany(fetchType = FetchType.EAGER)
private Set<Role> roles;
// constructors, getters, setters, equals/hashcode based on id
}
当我在存储库中执行这样的自定义查询时:
@Query("""
FROM User user
WHERE user.country = ?1
""")
public Set<User> getUserByCountry(String country);
...我得到了一个Set<User>
,但是他们的roles
属性是由Hibernate延迟加载的;我可以从SQL查询日志中清楚地看到这一点。一个角色查询被发送到每个用户的数据库。
现在,我已经有一段时间了,我清楚地记得FetchType.EAGER
是不受欢迎的,因为它影响了所有查询,而且您不能选择退出它。即使roles
引用被标记为EAGER
,也会执行延迟提取。这种行为在Hibernate的最新(主要)版本中是否发生了变化?我可以告诉Hibernate总是在默认情况下为所有定制查询提取渴望关联吗?
我试着使用@EntityGraph
显式地告诉自定义查询急切地获取roles
引用,这很好用,但是如果没有提供@EntityGraph
注解,我强烈希望hib从实体的注解中推断出这个信息。
编辑:我昨天验证了 Boot 和hib5.x的获取行为 * 实际上是 * 不同的。这似乎是hib6.x的事情。
1条答案
按热度按时间szqfcxe21#
生成的SQL查询应该包含一个join来获取
roles
作为主查询的一部分。在您的真实的模型中,当您有多个这样的渴望收集时,Hibernate必须发出单独的查询以避免多个包获取,这将改变结果的基数。但是,如果您只有一个渴望收集,请在问题跟踪器(https://hibernate.atlassian.net)中创建一个问题,并使用一个重现该问题的测试用例(https://github.com/hibernate/hibernate-test-case-templates/blob/master/orm/hibernate-orm-6/src/test/java/org/hibernate/bugs/JPAUnitTestCase.java)。