这是我的实体:
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。然而,他们提到了对这种方法的以下保留态度(我完全同意):
请注意,这主要是一种营销功能;优化行
读取比列读取的优化重要得多。
因此,在您确认这确实是应用程序中的瓶颈之前,我不建议在这条路上走得太远(例如,这种获取调整可能是过早优化的症状)。
UPDATE:
正如所指出的,JPA 确实将是否延迟获取简单列(非关联)的决定权留给了提供者。
EAGER 策略是对持久性提供者的要求
运行时必须急切地获取数据。 LAZY 策略是
向持久化提供程序运行时提示应获取数据
第一次访问时是惰性的。允许实施
急切地获取已使用 LAZY 策略提示的数据
指定的。特别是,延迟获取可能仅适用于
使用基于属性的访问的基本映射。
从 Hibernate 5 开始,添加了对字节码增强的官方支持,这可能允许延迟属性获取。
来自最新的 Hibernate 文档我们有:
2.3.2
fetch - FetchType(默认为 EAGER)
定义是否应急切或延迟获取此属性。
JPA 表示 EAGER 是对提供者(Hibernate)的要求
获取所有者时应获取该值,而 LAZY 是
仅提示当属性为
已访问。 Hibernate 会忽略基本类型的此设置,除非您
正在使用字节码增强。
下一个片段描述了字节码增强的优点。
延迟属性加载
将此视为部分加载支持。本质上你可以告诉
Hibernate 仅应加载实体的一部分
从数据库获取以及何时应加载其他部分
以及。请注意,这与基于代理的想法有很大不同
延迟加载,以实体为中心,实体的状态是
根据需要立即加载。通过字节码增强,单独
根据需要加载属性或属性组。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)