[英]Hibernate: n+1 and slow performance with Entity Graph
We did an upgrade to Hibernate 5, after which we began to experience performance issues. 我们对Hibernate 5进行了升级,此后我们开始遇到性能问题。
We have several entities with associations like this: 我们有几个具有以下关联的实体:
@Entity
@Table(name = "EVENT")
public class Event {
@Id
@Column(name = "ID")
private Long id;
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "LOCATION", referencedColumnName = "ID")
private Location location;
}
@Entity
@Table(name = "LOCATION")
public class Location {
@Id
@Column(name = "ID")
private Long id;
}
We are using the Criteria API to fetch the data from the database. 我们正在使用Criteria API从数据库中获取数据。
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<Event> query = cb.createQuery(Event.class);
Root<Event> from = query.from(Event.class);
query.select(from).where(from.get("id").in(1, 2, 3));
TypedQuery<Event> tQuery = entityManager.createQuery(query);
tQuery.setMaxResults(1000);
tQuery.getResultList();
Previously (version 4, old Criteria API), Hibernate generated one select with a join statement that fetched all the data, just based on the FetchType.EAGER, but with Hibernate 5, it creates multiple additional queries for fetching the 'location' data - the N+1 problem. 以前(第4版,旧的Criteria API),Hibernate生成了一个join语句,仅基于FetchType.EAGER提取了所有数据,但是使用Hibernate 5,它创建了多个附加查询来获取“位置”数据- N + 1问题。
Now, we have tried JPA Entity Graph, with mixed results. 现在,我们尝试了JPA实体图,但结果复杂。 We were able to reduce the number of queries (no N+1 now), but on the other hand, the performance of the system is even slower.
我们能够减少查询的数量(现在没有N + 1了),但是另一方面,系统的性能甚至更慢。
My questions are: 我的问题是:
(We use SQL Server, Tomcat, Hibernate 5.2.10, Java 8.) (我们使用SQL Server,Tomcat,Hibernate 5.2.10,Java8。)
To get the earlier behaviour of fetching location data along with join in a single query
can be achieved by adding the fetch
为了获得较早的
fetching location data along with join in a single query
中进行fetching location data along with join in a single query
行为,可以通过添加fetch
来实现
from.fetch("location", javax.persistence.criteria.JoinType.LEFT);
So your code would look like: 因此您的代码如下所示:
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<Event> query = cb.createQuery(Event.class);
Root<Event> from = query.from(Event.class);
from.fetch("location", javax.persistence.criteria.JoinType.LEFT);
query.select(from).where(from.get("id").in(1, 2, 3));
TypedQuery<Event> tQuery = entityManager.createQuery(query);
tQuery.setMaxResults(1000);
tQuery.getResultList();
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.