JPA auto flush before any query

放肆的年华 提交于 2021-02-16 08:38:25

问题


From JPA documentation I can see that the AUTO is the default flush mode, flush should happen before any query execution. I have tried this on spring boot jpa and I can see the flush won't happen on queries from different entities , is that expected ? even though different entity may have relation to it ( Department <--> Person here )

The flush should trigger before any query according to this article : https://vladmihalcea.com/how-do-jpa-and-hibernate-define-the-auto-flush-mode/

// this triggers flush //
 Person person = personRepository.findById(5L).get();
 person.setName("hello test");
 Person person1 = (Person) entityManager.createQuery("select person from Person 
 person where person.id=11").getSingleResult(); // flush before query



// this doesn't trigger flush even if  the department has the person //
 Person person = personRepository.findById(5L).get();
 person.setName("hello test");
 Department department= (Department) entityManager.createQuery("select 
 department from Department
department where department.id=1").getSingleResult();

Update:

I noticed the flush happens for JPQL queries on the same table only that has the DML , while for native sql queries it will always flush before any query if there is DML before. even though no flush happens the JPQL return the managed entity with modification not the one in DB. can anyone please explain if this follow JPA standard or not ?


回答1:


As JPA is a specification this question is simple to answer. Check out the spec :-)

3.10.8 Queries and Flush Mode

The flush mode setting affects the result of a query as follows. When queries are executed within a transaction, if FlushModeType.AUTO is set on the Query, TypedQuery, or StoredProcedureQuery object, or if the flush mode setting for the persistence context is AUTO (the default) and a flush mode setting has not been specified for the query object, the persistence provider is responsible for ensuring that all updates to the state of all entities in the persistence context which could potentially affect the result of the query are visible to the processing of the query. The persistence provider implementation may achieve this by flushing those entities to the database or by some other means. If FlushModeType.COMMIT is set, the effect of updates made to entities in the persistence context upon queries is unspecified.

If the persistence context has not been joined to the current transaction, the persistence provider must not flush to the database regardless of the flush mode setting.

package javax.persistence;
public enum FlushModeType {
COMMIT,
AUTO
}

If there is no transaction active, the persistence provider must not flush to the database

https://download.oracle.com/otn-pub/jcp/persistence-2_1-fr-eval-spec/JavaPersistence.pdf?AuthParam=1561799350_4cc62583442da694a6a033af82faf986

Then there is the Hibernate Doc:

6.1. AUTO flush

By default, Hibernate uses the AUTO flush mode which triggers a flush in the following circumstances:

  • prior to committing a Transaction

  • prior to executing a JPQL/HQL query that overlaps with the queued entity actions

  • before executing any native SQL query that has no registered synchronization

https://docs.jboss.org/hibernate/orm/5.4/userguide/html_single/Hibernate_User_Guide.html#flushing



来源:https://stackoverflow.com/questions/56812221/jpa-auto-flush-before-any-query

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!