强制延迟加载通常急切的属性

Force lazy loading of usually eager attributes

如何强制特定查询延迟加载通常具有预先加载的属性? EntityGraphType.FETCH 不工作。

@NamedEntityGraph(name="negGraphName",attributeNodes={
      @NamedAttributeNode("name"),
      @NamedAttributeNode("grup")})
class User{
  private String name;  

  @ManyToOne
  private UserGroup grup;

  @ManyToMany(fetch=FetchType.EAGER)
  protected Set<Authority> authoritiesList;
}

interface UserRepository extends CrudRepository<String, User>{
  @EntityGraph(value="negGraphName", type=EntityGraphType.FETCH)
  @Query("<custom query here>")
  private Collection<User> getUsersInSpecialQuery(@Param("paramName") String paramName);
}

基本上,当我调用 userRepository.getUsersInSpecialQuery() 时,初始查询加入对象,但不加入权限,但是 Hibernate 无论如何都会使用单独的 SQL 查询每个用户结果初始化权限列表,这是非常低效的。此外,它还初始化了甚至没有标记为 Eager 的 DomainObject 对象图父对象。

在 authorityList 上禁用 fetch=FetchType.EAGER 会禁用额外的每用户查询,但我仍然希望为所有其他查询急切地获取它。

EntityGraphType.Fetch 的 javadoc 说:

When the javax.persistence.fetchgraph property is used to specify an entity graph, attributes that are specified by attribute nodes of the entity graph are treated as FetchType.EAGER and attributes that are not specified are treated as FetchType.LAZY

但显然我不是这种情况


Hibernate : Force lazy-loadding on eager field <-- 没有解决方案

Fetch Type LAZY still causes Eager loading Hibernate Spring data <-- 声称问题是惰性属性是通过查看加载的,但是在我的例子中,我是在休眠状态下逐步执行的,它是在用户对象的具体化过程中

你不能让 EAGER 协会变得懒惰。我建议你让它变得懒惰,并在所有你想要它的查询中 EAGERly JOIN FETCH authoritiesList 这样他们就很有效了。

另一个选项是 子实体,它与您当前的用户实体基本相同,映射到相同的数据库 table 但没有您不想要的关系:

@Entity
@Table(name="SAME_TABLE_AS_USER_ENTITY")
class BasicUser{
  private String name;  

  @ManyToOne
  private UserGroup grup;

}

另一种选择是继承。

我想我终于明白了。 spring-data 的 EntityGraphTypes 指的是不同的事物。此枚举只是以下 jpa 查询提示的快捷方式

  • javax.persistence.fetchgraph 指查询是如何建立的,
  • javax.persistance.loadgraph指的是如何从结果集中填充对象。

所以没有超过@Robert_Niestroj推荐的答案