如何在spring-data-japa中使用本机查询时减少刷新?

时间:2015-08-03 06:39:48

标签: hibernate spring-data-jpa

我目前正在使用spring 4.2和hibernate 4.3进行项目。

通过分析,我发现使用@org.springframework.data.jpa.repository.Query(nativeQuery=true)的存储库方法需要时间。这是因为org.hibernate.pa.internal.QueryImpl.getResultList()在内部调用javax.persistence.EntityManager.flush(),无论您使用什么刷新模式。如果很多实体都在持久化上下文中,那么flush()需要时间。

我认为可以通过调用org.hibernate.SQLQuery.addSynchronizedEntityClass()来避免这种情况,但我不知道使用spring-data-jpa调用addSynchronizedEntityClass()的最佳方法(或任何其他方式告诉hibernate不冲洗。)

减少冲洗的最佳做法是什么?

2 个答案:

答案 0 :(得分:0)

您可以为所需(或所有)会话设置flush modeCOMMIT。请记住,如果查询取决于脏会话状态,请手动刷新会话。

答案 1 :(得分:0)

对于我正在开发的项目,我们正在从Hibernate EJB EM 3.6迁移到Hibernate JPA EM 4.3.8,并遇到了这种情况。我发现了一个hibernate错误,它讨论了如何将此刷新添加到本机查询(HHH-8487)。它至少解释了flush的来源,但它似乎建议你告诉本机查询哪些实体要“同步”。

Query jpaSqlQuery = entityManager.createNativeQuery( ... );
jpaSqlQuery.unwrap( org.hibernate.SQLQuery.class )
           .addSynchronizedEntityClass( Person.class );

在此之前,我认为我们的应用程序在我们知道会受到我们在特定代码线程中所做的更改影响的查询之前,正在调用flush。在许多情况下,我们没有。但我认为上面的代码至少使查询知道可能涉及哪些实体。您甚至可以添加多个实体类作为此同步的一部分。

这是一个解决方案,但迁移现有应用程序可能需要花费大量时间,并且可能难以生成通用解决方案。