Hibernate忽略了fetchgraph

Pav*_*l_K 8 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
}
Run Code Online (Sandbox Code Playgroud)

这就是我获取人员名单的方式:

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
Run Code Online (Sandbox Code Playgroud)

如果我理解了fetch图,它必须只加载我指定的那些字段.但是,字段"birthDate"也被加载.除了我看到在hibernate sql查询4列被选中.

怎么解决?我使用hibernate 5.1.0作为JPA提供程序.

Pac*_*ace 5

实体图形意在控制哪些关系(例如一到一,一到多等)懒惰地或热切加载.它们可能不适用于加载单个列(取决于提供者).

Hibernate对此有一些支持,但是在这里描述的工作相当困难.然而,他们提到了对这种方法的以下缄默(我完全同意):

请注意,这主要是营销功能; 优化行读取比列读取的优化要重要得多.

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

更新:

正如所指出的那样,JPA确实会向提供者说明是否延迟提取简单列(非关联).

EAGER策略是持久性提供程序运行时的一项要求,必须急切地获取数据.LAZY策略是持久性提供程序运行时的提示,即数据在首次访问时应该被懒惰地获取.允许实现急切地获取已指定LAZY策略提示的数据.特别是,延迟提取可能仅适用于使用基于属性的访问的基本映射.

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

最新的Hibernate文档中我们得到:

2.3.2

fetch - FetchType(默认为EAGER)

定义是应该急切地还是懒惰地获取此属性.JPA表示EAGER是提供者(Hibernate)要求在获取所有者时获取值的要求,而LAZY仅仅是在访问属性时提取值的提示.除非使用字节码增强,否则Hibernate会忽略基本类型的此设置.

这个下一个片段描述了字节码增强的优点.

延迟属性加载

将此视为部分加载支持.从本质上讲,你可以告诉Hibernate只有在从数据库中取出时才加载实体的一部分,以及何时加载其他部分.请注意,这是懒加载的基于代理的想法是在实体的状态,需要的是在一次加载实体为中心的有很大的区别.通过字节码增强,可以根据需要加载单个属性或属性组.