我有3个实体。分公司,主题,话题。 分支具有主题列表,主题具有主题列表。也 subjectList和topicList都是懒惰的。我想要获取所有分支 包括单个查询中的主题和主题。
1
@Entity
public class Branch implements Serializable
{
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
private String name;
@OneToMany(mappedBy = "branch")
private List<Subject> subjectList;
//Getters and Setters
}
2
@Entity
public class Subject implements Serializable
{
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
private String name;
@ManyToOne()
private Branch branch;
@OneToMany(mappedBy = "subject")
private List<Topic> topicList;
//Getters and Setters
}
3
@Entity
public class Topic implements Serializable
{
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
private String name;
@ManyToOne()
private Subject subject;
//Getters and Setters
}
我尝试了下面的方法,但它没有用。
@NamedEntityGraph(name="branch_subject",
attributeNodes = {
@NamedAttributeNode(value="name"),
@NamedAttributeNode(value="subjectList", subgraph = "subjectListGraph")
},
subgraphs = {
@NamedSubgraph(name="subjectListGraph",
attributeNodes = {
@NamedAttributeNode(value="name"),
@NamedAttributeNode(value = "topicList", subgraph = "topicListGraph")
}
),
@NamedSubgraph(name="topicListGraph",
attributeNodes = {
@NamedAttributeNode("name")
}
)
}
)
以下代码也用于从中获取数据 数据库,我使用JPQL如下
EntityGraph branchEntityGraph = entityManager
.getEntityGraph("branch_subject");
Branch branch = entityManager
.createQuery("SELECT b from Branch b WHERE b.id=:ID",
Branch.class)
.setHint("javax.persistence.loadgraph", branchEntityGraph)
.setParameter("ID", branch1.getId()).getResultList().get(0);
这给出了以下异常
org.hibernate.loader.MultipleBagFetchException: cannot simultaneously fetch multiple bags
答案 0 :(得分:8)
Hibernate不允许您获取多个行李,因为它最终会获取笛卡尔积。
您make your collection Sets, instead of Lists并面临笛卡尔产品性能问题。
如果您已经有INNER JOIN关系,那么您可以简单地fetch from the inner-most Child up to the root然后重新组合该结构。由于查询如下所示,因此效率更高:
select t
from Topic t
join t.subject s
join s.branch b
我在文章中描述的EntityGraphBuilder
很容易适应您的使用案例。
答案 1 :(得分:0)
我想我也有类似的问题。我所有的Device
实体都有一个Transaction
对象,在我的情况下,该对象存储datetime
以及该特定对象的用户和计算机信息。还有一个DeviceType
实体,该实体具有事务对象,并且与我的Device
实体具有多对一关系。因此,实际上,我与此Transaction Entity
有1级和2级嵌套关系。因此,我有一些嵌套异常。使用Subgraph
为我解决了这个问题。这是我的NamedEntityGraphs
定义代码。希望对您有所帮助:
@NamedEntityGraphs(value = {
@NamedEntityGraph(name = "Device.AllRelations",
attributeNodes = {
@NamedAttributeNode("transaction"),
@NamedAttributeNode(value = "deviceType", subgraph = "DeviceType.Transaction")
},
subgraphs = {
@NamedSubgraph(name = "DeviceType.Transaction", attributeNodes = {
@NamedAttributeNode("transaction")
})
}
),
@NamedEntityGraph(name = "Device.TransactionOnly", attributeNodes = {
@NamedAttributeNode("transaction")
}),
})