强制延迟加载通常渴望的属性

时间:2017-01-19 07:09:26

标签: hibernate spring-data-jpa eager-loading

如何强制特定查询延迟加载一个通常具有急切加载的属性? 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 QUERY PER USER RESULT初始化权限列表,这是非常低效的。此外,它初始化DomainObject对象图父级,甚至没有标记为Eager。

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

EntityGraphType.Fetch的javadoc说:

  

当javax.persistence.fetchgraph属性用于指定。时   实体图,由属性节点指定的属性   实体图被视为FetchType.EAGER和属性   未指定的被视为FetchType.LAZY

但很明显,对我来说并非如此

Hibernate : Force lazy-loadding on eager field&lt; - 没有解决方案

Fetch Type LAZY still causes Eager loading Hibernate Spring data&lt; - 声称问题是lazy属性是通过查看加载的,但是在我的情况下,我在hibernate中逐步完成,并且是在User对象的实现过程中

2 个答案:

答案 0 :(得分:1)

你不能做一个EAGER assosciation LAZY。我建议你把它变成LAZY,并且在你想要它的所有查询中EAGERly JOIN FETCH authoritiesList所以它们实际上是EAGER。

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

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

  @ManyToOne
  private UserGroup grup;

}

另一种选择是继承。

答案 1 :(得分:0)

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

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

所以没有回答@Robert_Niestroj推荐的