当前位置: 首页 > 知识库问答 >
问题:

Hibernate:n1和实体图的低性能

锺宜
2023-03-14

我们升级到Hibernate 5,之后我们开始遇到性能问题。

我们有几个实体有这样的关联:

@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;
}

我们正在使用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();

以前(版本4,旧的Criteria API),Hibernate仅基于FetchType生成一个带有获取所有数据的连接语句的选择。EAGER,但使用Hibernate 5,它会创建多个额外的查询来获取“位置”数据——N 1问题。

现在,我们尝试了JPA Entity Graph,结果喜忧参半。我们能够减少查询次数(现在没有N 1),但另一方面,系统的性能甚至更慢。

我的问题是:

  1. 还有什么其他方法可以消除N 1查询问题
  2. 在什么情况下实体图会对性能产生负面影响

(我们使用SQL Server、Tomcat、Hibernate 5.2.10和Java 8。)

共有1个答案

安明亮
2023-03-14

要在单个查询中获得获取位置数据以及join的早期行为,可以通过添加获取

from.fetch("location", javax.persistence.criteria.JoinType.LEFT);

所以你的代码看起来像:

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();

 类似资料:
  • 我正在测试我在activeMQ上工作的代码, 我在里面使用。当我发送大约1000个并发请求来将我的消息排队时,将所有消息排队需要很长时间,有时它只是挂在中间,过了一段时间又开始返回。 我正在使用JDBC消息存储,我知道这可能会影响性能。 这对性能的影响主要是由于虚拟主题吗?,因为在activemq网站上,他们指定了非常高的主题性能(当然是在理想条件下) P、 S:1消息排队和出列大约需要13-15

  • 使用实体图时,JPA Level 1缓存是如何工作的? 如果我打电话: (顺便说一下,我在这里使用Spring Data,这是我自定义存储库中的一个方法,但这与问题无关)。 这将使用适当的SELECT语句访问数据库,该语句包括系统和制造商表所需的所有连接。这是完美的工作和预期。 然而,如果我称之为: 第一个findOne调用将仅通过选择工具表来命中数据库,这是正常的,但第二个findOne不会命中

  • 我正在使用jpa 2.1 EntityGraphs来修改不同的jpa查询,在某些情况下,EntityGraph不能按预期工作。我正在努力解决的简单用例是: 作者作为父类,与Book子类具有单向一对多关系,我想检索给定书名的作者结果,类似于findAllAuthorsByBookName。 我的作者类是这样的 书没有引用作者,所以它看起来像这样 Generic Entity类仅具有id和name属性

  • 问题内容: 使用这些JPA属性 Ehcache对于同一查询效率不高, 问题与QueryCache类的namedParameters.hashCode()函数有关,它为同一查询生成了不同的HashCode! 与班级有关 它将为同一Array对象[01,1]生成一个不同的(新)hachCode! 对于数组,此hashCode方法应该是递归的 问题答案: 递归版本完全正常 类org.hibernate.

  • 我想知道是否有办法微调JPA/Hibernate以管理以下用例。我有以下对象模型: 然后我执行以下代码: 我想要实现的是: > 根据用例调整Hibernate,即不更改实体类; 使Hibernate执行两个查询: 上面的代码片段与Child-Sunder lazy fetch的基本行为是: (1)执行对实体的一个查询; (2)对实体的所有实体执行一个查询; (3)n个查询,每个实体一个。 通过阅读

  • 使用thoses和JPA属性 Ehcache对于相同的查询不是有效的, 问题与QueryCache类的函数namedParameters.hashCode()有关,它为同一个查询生成不同的HashCode! 这与类有关 它为同一个数组对象[01,1]生成一个不同的(新的)hachCode! 此hashCode方法对于数组应该是递归的