Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JPA auto flush before any query

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 ?

like image 909
Mohammad Karmi Avatar asked Jun 28 '19 19:06

Mohammad Karmi


1 Answers

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

like image 181
Simon Martinelli Avatar answered Oct 10 '22 15:10

Simon Martinelli