java - Hibernate 忽略 fetchgraph

标签 java hibernate jpa entitygraph

这是我的实体:

public class PersonItem implements Serializable{
    @Id
    @Column(name="col1")
    private String guid;

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

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

    @Column(name="col4")
    private Date birthDate;
 //+getters and setters
}

这是我获取人员列表的方式:

Query query = em.createQuery("Select p from PersonItem p WHERE p.guid IN (:guids)");
EntityGraph<PersonItem> eg = em.createEntityGraph(PersonItem.class);
eg.addAttributeNodes("guid");
eg.addAttributeNodes("name");
eg.addAttributeNodes("surname");
query.setHint("javax.persistence.fetchgraph", eg);
query.setParameter("guids", guids);
List<PersonItem> list=query.getResultList();
em.close();
// And now I iterate result AFTER EM CLOSE
....iterate

如果我正确理解获取图形,它必须只加载我指定的那些字段。但是,字段“birthDate”也被加载。此外,我看到在 hibernate sql 查询中选择了 4 列。

如何解决?我使用 hibernate 5.1.0 作为 JPA 提供程序。

最佳答案

实体图旨在控制延迟加载或急切加载哪些关系(例如一对一、一对多等)。它们可能不适用于加载单个列(这取决于提供商)。

Hibernate 对此提供了一些支持,但要开始工作相当困难,描述了 here .然而,他们提到了以下对这种方法的沉默(我完全同意):

Please note that this is mostly a marketing feature; optimizing row reads is much more important than optimization of column reads.

所以我不建议在这条路上走得太远,直到您确认这确实是您应用程序中的瓶颈(例如,这种获取调整可能是过早优化的症状)。

更新:

正如所指出的,JPA 确实让提供者决定是否延迟获取简单列(非关联)。

The EAGER strategy is a requirement on the persistence provider runtime that data must be eagerly fetched. The LAZY strategy is a hint to the persistence provider runtime that data should be fetched lazily when it is first accessed. The implementation is permitted to eagerly fetch data for which the LAZY strategy hint has been specified. In particular, lazy fetching might only be available for Basic mappings for which property-based access is used.

从 Hibernate 5 开始,添加了对字节码增强的官方支持,这可能允许延迟属性获取。

来自latest Hibernate docs我们有:

2.3.2

fetch - FetchType (defaults to EAGER)

Defines whether this attribute should be fetched eagerly or lazily. JPA says that EAGER is a requirement to the provider (Hibernate) that the value should be fetched when the owner is fetched, while LAZY is merely a hint that the value be fetched when the attribute is accessed. Hibernate ignores this setting for basic types unless you are using bytecode enhancement.

下一个片段描述了字节码增强的优势。

Lazy attribute loading

Think of this as partial loading support. Essentially you can tell Hibernate that only part(s) of an entity should be loaded upon fetching from the database and when the other part(s) should be loaded as well. Note that this is very much different from proxy-based idea of lazy loading which is entity-centric where the entity’s state is loaded at once as needed. With bytecode enhancement, individual attributes or groups of attributes are loaded as needed.

关于java - Hibernate 忽略 fetchgraph,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37054082/

相关文章:

java - 将 Scala 单位转换为 Java Void

java - ThriftSecurityException(用户 :root, 代码:BAD_CREDENTIALS)

java - Android Studio - 保存所有玩过的游戏的累积分数

java - 每次运行 Junit 测试时实体管理器都为空

java - Hibernate,JPA无法删除一对多关系

Java 通配符和泛型? super T 和?延伸 T

java - JDBC 和 Hibernate 之间的中间地带?

java - JPA/hibernate : StringClobType deprecated

java - hibernate : @JoinColumn behaviour in uni-directional and bi-directional mapping

java - 使用SQL查询创建索引和在JPA中使用@Index创建索引的区别