【问题标题】:Entity Graph ignored when loading related entities加载相关实体时忽略实体图
【发布时间】:2018-03-26 17:42:26
【问题描述】:

我在我的 Person 实体中定义了一个实体图。当我将 phone 属性声明为属性节点时,会创建一个 join 子句,并且只执行一个 select,正如预期的那样。但是,当我从实体图中删除电话属性时,电话字段仍然被加载,但现在每个人都重新检索了一个新的选择查询。是否可以忽略特定 EntityGraph 中的属性?

个人实体:

@Entity
@Table(name = "person")
@NamedEntityGraph(
    name = Person.PERSON_LAZY,
    attributeNodes = {}
)
public class Person {

    public static final String Person_LAZY = "person.lazy";

    @Id
    @Column(name = "id")
    private Long id;

    @Column(name = "name")
    private String name;

    @JoinColumn(name = "phone")
    @ManyToOne
    private Phone phone;
}

PersonRepository:

@Repository
public interface PersonRepository extends JpaRepository<Person, Long> {

    @EntityGraph(value = Person.PERSON_LAZY, type = EntityGraphType.FETCH)
    @Query("SELECT p FROM Person p")
    public List<Person> findAllLazy();  
}

【问题讨论】:

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


    【解决方案1】:

    简短的回答,不。实体图或任何其他方式都不可能。

    @ManyToOne 关系默认是急切加载的。你必须让它变得懒惰以防止它以任何方式被加载。

    一般的建议是,由于您可以急切地加载惰性关系,但不能延迟地加载急切的关系,因此您应该优先考虑惰性关系,以防万一。

    是的,这包括实体图和所有其他可能的技巧。如果一个关系是默认的或显式的,它永远不会是惰性的。即使使用实体图,这显然也是一个设计选择/实现细节,但没有改变它的计划。

    【讨论】:

    • 我可以设置一个默认的EntityGraph吗?那么我所有的查询都会使用它吗?
    • 可能,但是您是否明白您不能使用实体图将急切的关系转换为懒惰的关系?您必须将其显式设置为 FetchType.LAZY
    • 应用程序已经在使用这个带有急切获取类型的实体。我想我可以保留 Eager fetch 类型并创建一个惰性 EntityGraph,根据文档,使用 FETCH 策略是可能的。 “您通过在包含实体的文件中导入 javax.persistence.fetchgraph 来指定 FETCH 作为您的策略。在这种情况下,您的实体图中指定的所有属性都将被视为 FetchType.EAGER,所有未指定的属性将被视为 FetchType .LAZY"
    • 我知道它使用的是 Eager fetch 类型。这就是我的回答所说的。现在我最后一次解决这个问题(可能是 1.5 年前)得出的结论是,没有办法从渴望中恢复到懒惰,即使文档暗示了这一点。我不记得这是否是 Hibernate 的实现细节以及它是否发生了变化,但根据我早期的侦探工作,你不能拥有你想要的东西。不过,我很高兴被证明是错误的。当我发现它无法完成时,我感到非常失望。
    • 看来你是对的,我不能使关系 Lazy 和可选的 Eager。我也对文档和实现“获取配置文件”非常适合这种情况感到失望。感谢您的回答。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-10-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-19
    • 2011-04-09
    • 1970-01-01
    相关资源
    最近更新 更多