Hibernate 忽略 fetchgraph

Hibernate ignores fetchgraph

这是我的实体:

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" 也被加载。此外,我看到在休眠 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.