Java JPA2:N+1使用带有JOIN的查询进行偶数选择
在我的应用程序中,我有一个实体A,其中包含一个应急切获取的实体B列表:Java JPA2:N+1使用带有JOIN的查询进行偶数选择,java,jpa,join,eager,Java,Jpa,Join,Eager,在我的应用程序中,我有一个实体A,其中包含一个应急切获取的实体B列表: @Entity public class A { ... /* @OrderBy("cValue.id ASC") */ @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL) @JoinColumn(name="A_ID", nullable=false) private List<B> BEntrie
@Entity
public class A
{
...
/* @OrderBy("cValue.id ASC") */
@OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
@JoinColumn(name="A_ID", nullable=false)
private List<B> BEntries = new ArrayList<B>();
...
}
@Entity
public class B
{
...
@ManyToOne
@JoinColumn(name = "C_ID", nullable = false)
private C cValue;
...
}
好了,现在生成的SQL查询包含了构建完整的A对象所需的所有左连接。。。但它仍然在B表上执行其他N个查询!
我最初认为它来自于我在Bentries参数上添加的@OrderBy注释,但即使删除了,它仍在进行N+1选择,而不是1选择
知道为什么会这样吗?。。。甚至为什么它在实体中急切获取的集合上默认不执行左连接?您需要的是连接获取,而不仅仅是连接。我认为您需要更改critRoot.join到critRoot.fetch。太好了,它现在只做一次选择。这很简单,谢谢顺便说一句,为什么它在默认情况下执行N+1选择,而不是这样的获取?有很多原因可以解释为什么您可能希望加入一个单独的表而不实际获取它。可能需要按相关表中的列进行筛选,或按相关表中的列进行排序。但是,您不需要在结果中返回数据。考虑一下我想从我所有的朋友那里看到所有帖子的情况。嗯,我不在乎我的朋友是谁,我只在乎我得到的回复是他们发来的。在这种情况下,您只需要一个没有数据的连接,所以不可能通过注释来完成?我在@fetchmode.JOIN上遇到了同样的问题,但它不工作。
CriteriaBuilder critBuilder = em.getCriteriaBuilder();
CriteriaQuery<A> critQuery = critBuilder.createQuery(A.class);
Root<A> critRoot = critQuery.from(A.class);
critQuery.select(critRoot);
Join<A,B> joinAB = critRoot.join(A_.BEntries, JoinType.LEFT);
joinAB.join(B_.cValue, JoinType.LEFT);