我上课
public class ToolSet {
...
@OneToOne(fetch = FetchType.EAGER)
private Contractor assignedTo;
...
}
public class Contractor {
...
@ManyToMany(cascade = {CascadeType.ALL}, fetch = FetchType.EAGER)
@JoinTable(
name = "contractors_docs_photos",
joinColumns = @JoinColumn(
name = "contractor_id", referencedColumnName = "id"),
inverseJoinColumns = @JoinColumn(
name = "image_id", referencedColumnName = "id"))
private Set<Image> idPhoto;
...
}
现在当我查询工具集时,我得到以下信息
"toolset": [
{
...
"_embedded": {
"assignedTo": {
"firstName": "firstName",
}
}
}
如何将嵌套对象也加载到Contractor(照片)中?这样,当我加载工具集时,我会看到承包商,在concorcor内部,我会看到它的照片
答案 0 :(得分:0)
首先,我们应该看看您的int i
关系本身的实现。正如Vlad Mihalcea在this article中详细解释的那样,@ManyToMany
不是一个好的选择。这导致许多不必要的数据库请求。
此外,级联所有更改可能会导致严重的问题。删除特定对象可以自动级联以删除许多其他对象。由于described in this article(向下滚动一点),对于FetchType.EAGER
关系,应避免使用CascadeType.REMOVE
。 @ManyToMany
包括CascadeType.ALL
。相反,您应该使用REMOVE
在this Stackoverflow answer中可以找到@ManyToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE})
关系的另一个示例。
惰性关系(如提到的“好” @ManyToMany
)不是由Hibernate(Spring Data自动使用的ORM)初始化的。在相应的变量中只能找到具有相关主键的代理。当有人尝试访问变量时,会自动从数据库中加载完整对象。这将导致其他数据库请求。
如果您已经预先知道需要该对象(访问变量),则应在从数据库请求父对象时初始化关系(当您从数据库请求@ManyToMany
时,其{{1 }}也应加载。
在SQL中,这意味着这些不同表之间的联接。在JPA中,联接并不自动意味着已加载数据。因此,您应该使用访存联接或实体图来初始化惰性注释。 This article很好地概述了如何使用这些不同的初始化方式。
在JPA中,有多种实现数据库请求的方式:JPQL作为查询语言和Criteria API(更易于重构,更不易出错)。我是Criteria API的爱好者,我将向您展示一个示例,说明如何使用它初始化关系以及实体图的用法。
ToolSet
在此示例中,我假设您的idPhoto
主键称为public Optional<ToolSet> findById(long id) {
EntityGraph<ToolSet> graph = entityManager.createEntityGraph(ToolSet.class);
graph.addAttributeNodes("assignedTo");
Subgraph<Contractor> subgraph = graph.addSubgraph("assignedTo");
subgraph.addAttributeNodes("idPhoto");
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<ToolSet> cq = cb.createQuery(ToolSet.class);
Root<ToolSet> root = cq.from(ToolSet.class);
cq.where(cb.equal(root.get("id"), id)); // Assumption of id as PK
TypedQuery<ToolSet> typedQuery = entityManager.createQuery(cq);
typedQuery.setHint("javax.persistence.fetchgraph", graph);
ToolSet response = null;
try {
response = typedQuery.getSingleResult();
}
catch(NoResultException nre) {}
return Optional.ofNullable(response);
}
。要在编译时更好地查看错误,请查看hibernate-jpamodelgen。然后,您可以编写诸如ToolSet
之类的东西。
以上,我使用id
。不必使用。无论如何,您可以重新研究使用它的优势。