Close

JPA - Flushing Persistence Context

[Updated: Dec 6, 2017, Created: Sep 16, 2017]

By invoking EntityManager#flush() method we can synchronize the current persistence context to the underlying database.

This operation will cause DML statements (insert/update/delete etc) to be executed to the database but the current transaction will not be committed. That means flush() will not make current changes visible to other EntityManager instances or other external database clients; that will only happen at the transaction commit. In other words flush() operation will only flush the current memory cache from EntityManager to the database session.

When should we use flush()?

We will probably need flush() operation for performance reasons i.e. to empty the huge runtime memory cache accumulated within current EntityManager persistence context.

We might also need to use this operation for the next entity manager operations (within the same transaction), for example, where the database query (JPQL or native query) must be needed to retrieve some information which cannot be available locally within EntityManager persistence context.

Flush Mode

EntityManager#setFlushMode(FlushModeType) can be used to set one of the following flushing behavior:

  • FlushModeType.AUTO

    An automatic flush can be invoked before transaction commit. That is up to TransactionManager when an automatic flush should occur. This usually happens before a query execution. This is the default mode.

  • FlushModeType.COMMIT

    Flushing will only occur at transaction commit or when TransactionManager#flush() is used manually.

Example

The Entity

@Entity
public class Employee {
  @Id
  @GeneratedValue
  private Integer id;
  private String name;
  private String department;

  public Employee() {
  }

  public Employee(String name, String department) {
      this.name = name;
      this.department = department;
  }
    .............
}

Setting Flush Mode and using flush()

In this example, we are setting flush mode to FlushModeType.COMMIT, that means we want to take control and to use flush() manually.

public class ExampleMain {
    .............
  private static void persistEntity(EntityManagerFactory emf) {
      EntityManager em = emf.createEntityManager();
      em.setFlushMode(FlushModeType.COMMIT);
      List<Employee> employeeList = getNewEmployees();

      em.getTransaction().begin();
      for (Employee employee : employeeList) {
          em.persist(employee);
      }
      em.flush();
      showPersistedITEmployees(em);
      em.getTransaction().commit();
      em.close();
  }

  private static void showPersistedITEmployees(EntityManager em) {
      Query query =
              em.createQuery("Select e from Employee e where e.department ='IT'");
      System.out.println("-- IT employees persisted list --");
      List<Employee> list = (List<Employee>) query.getResultList();
      list.forEach(System.out::println);
  }
    .............
}

Output

-- IT employees persisted list --
Employee{id=2, name='Mike Volin', department='IT'}

If we comment out flush() call:

public class ExampleMain2 {
    .............
  private static void persistEntity(EntityManagerFactory emf) {
      EntityManager em = emf.createEntityManager();
      em.setFlushMode(FlushModeType.COMMIT);
      List<Employee> employeeList = getNewEmployees();

      em.getTransaction().begin();
      for (Employee employee : employeeList) {
          em.persist(employee);
      }
      // em.flush();
      showPersistedITEmployees(em);
      em.getTransaction().commit();
      em.close();
  }
    .............
}

Output

-- IT employees persisted list --

No IT employees printed. This demonstrates the use of flush() i.e. to make changes visible to next operations of the same EntityManager instance.

Note that if we don't set FlushModeType.COMMIT in above example and use the default one i.e. FlushModeType.AUTO, then JPA will do an automatic flush itself before query.getResultList() call and we don't have to use flush() ourselves.

Example Project

Dependencies and Technologies Used:

  • h2 1.4.196: H2 Database Engine.
  • hibernate-core 5.2.10.Final: The core O/RM functionality as provided by Hibernate.
    Implements javax.persistence:javax.persistence-api version 2.1
  • JDK 1.8
  • Maven 3.3.9

EntityManager#flush() Example Select All Download
  • flushing-persistence-context
    • src
      • main
        • java
          • com
            • logicbig
              • example
                • ExampleMain.java
          • resources
            • META-INF

    See Also