gpt4 book ai didi

java - 如何使用 JPA - EntityGraph 只加载实体@Basic 属性的一个子集?

转载 作者:行者123 更新时间:2023-11-30 07:43:25 25 4
gpt4 key购买 nike

我找到了这个 documentation关于实体图...阅读后,它让我想到您可以使用实体图来检索给定实体的 @Basic 字段的子集(直到现在,我已经使用用于检索关系的实体图,例如,加载员工[包括其所有属性]及其关联的部门[包括其所有属性])...

所以,我决定用一个小测试来尝试这个:

@Entity
@Table(name = "employee")
@NamedEntityGraphs({
@NamedEntityGraph(
name = "OnlyName",
attributeNodes = @NamedAttributeNode(value = "name")
)
})
public class Employee implements Serializable {
...
@Id
@Column(name = "code", updatable = false)
private Long code;

@Basic(fetch = FetchType.LAZY)
@Column(name = "name", nullable = false)
private String name;

@Basic(fetch = FetchType.LAZY)
@Column(name = "last_name", nullable = false)
private String lastName;

@Lob @Basic(fetch = FetchType.LAZY)
@Column(name = "picture", nullable = false)
private byte[] picture;

public Employee() {
super();
}
...
}

然后,为了检索我的实体,我使用了以下代码:

    private Employee retrieveFromDatabase(long code) {
EntityGraph<Employee> graph; // Material Entity Graph

Map<String, Object> map = new HashMap<>();

graph = (EntityGraph<Employee>) this.em.createEntityGraph("OnlyName");
map.put("javax.persistence.fetchgraph", graph);


return this.em.find(Employee.class, code, map);
}

现在,这段代码总是返回一个 Employee,其中包含从数据库中获取的所有字段;甚至 Hibernate 日志也显示了一个选择所有员工字段的查询:

Hibernate:选择 employee0_.code 作为 code1_0_0_,employee0_.last_name 作为 last_name2_0_0_,employee0_.name 作为 name3_0_0_,employee0_.picture 作为 picture4_0_0_ from employeeemployee0_ where employee0_.code=?
)

当我期待这样的查询时:select employee0_.code as code1_0_0_, mployee0_.name as name3_0_0_ from employee employee0_ where employee0_.code=?

那么,我做错了什么?有没有这个功能supported通过 hibernate ??

注意:为了测试,我使用的是 hibernate 5.0.10 和 wildfly10 ...

谢谢!

最佳答案

其实,你并没有做错什么。然而,您遗漏了 Hibernate ORM User Guide (v5.0.x) 中的一条重要信息.在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. See the BytecodeEnhancement for additional information on fetching and on bytecode enhancement.

因此:即使您正在向 em.find(..) 方法提供查询提示,这取决于 JPA 提供程序 - 这里:Hibernate - 决定是否获取基本属性热切与否。在您的情况下,Employee 实体仅包含 @Basic 属性。

有关引用、更多上下文以及更详细的解释,另请参阅此 tutorial .它涵盖了 "javax.persistence.fetchgraph""javax.persistence.loadgraph" 查询提示之间的差异,并具有演示 JPA 持久性提供程序 Hibernate 的上述行为的示例代码.

旁注:我检查过..

  • .. Hibernate ORM 用户指南 5.1 , 5.2 , 和 5.3 : 所有版本都包含关于忽略基本属性的默认策略的完全相同的声明。
  • ..官方JPA 2.1 specification document .在 (PDF) 第 117 页的第 3.7.4 节中,我们发现:

    The persistence provider is permitted to fetch additional entity state beyond that specified by a fetch graph or load graph.

JPA 规范中的后一引述支持 ORM 用户指南,即以这种方式实现它是可以的。

我的建议:

查看 Hibernate ORM 用户指南(见上文)中所述的BytecodeEnhancement

希望对您有所帮助。

关于java - 如何使用 JPA - EntityGraph 只加载实体@Basic 属性的一个子集?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53490655/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com