title: Spring Boot Data JPA - Modifying update query - Refresh persistence context
body: <p>I'm working with Spring Boot 1.3.0.M4 and a MySQL database.</p>
  
  <p>I have a problem when using modifying queries, the EntityManager contains outdated entities after the query has executed.</p>
  
  <h3>Original JPA Repository:</h3>
  
  <pre class="lang-java prettyprint-override"><code>public interface EmailRepository extends JpaRepository&lt;Email, Long&gt; {
  
      @Transactional
      @Modifying
      @Query("update Email e set e.active = false where e.active = true and e.expire &lt;= NOW()")
      Integer deactivateByExpired();
  
  }
  </code></pre>
  
  <p>Suppose we have <em>Email [id=1, active=true, expire=2015/01/01]</em> in DB.</p>
  
  <p>After executing:</p>
  
  <pre class="lang-java prettyprint-override"><code>emailRepository.save(email);
  emailRepository.deactivateByExpired();
  System.out.println(emailRepository.findOne(1L).isActive()); // prints true!! it should print false
  </code></pre>
  
  <hr>
  
  <h3>First approach to solve the problem: add <strong><em>clearAutomatically = true</em></strong></h3>
  
  <pre class="lang-java prettyprint-override"><code>public interface EmailRepository extends JpaRepository&lt;Email, Long&gt; {
  
      @Transactional
      @Modifying(clearAutomatically = true)
      @Query("update Email e set e.active = false where e.active = true and e.expire &lt;= NOW()")
      Integer deactivateByExpired();
  
  }
  </code></pre>
  
  <p>This approach clears the persistence context not to have outdated values, but it drops all non-flushed changes still pending in the EntityManager. As I use only <em><code>save()</code></em> methods and not <em><code>saveAndFlush()</code></em> some changes are lost for other entities :(</p>
  
  <hr>
  
  <h3>Second approach to solve the problem: custom implementation for repository</h3>
  
  <pre class="lang-java prettyprint-override"><code>public interface EmailRepository extends JpaRepository&lt;Email, Long&gt;, EmailRepositoryCustom {
  
  }
  
  public interface EmailRepositoryCustom {
  
      Integer deactivateByExpired();
  
  }
  
  public class EmailRepositoryImpl implements EmailRepositoryCustom {
  
      @PersistenceContext
      private EntityManager entityManager;
  
      @Transactional
      @Override
      public Integer deactivateByExpired() {
          String hsql = "update Email e set e.active = false where e.active = true and e.expire &lt;= NOW()";
          Query query = entityManager.createQuery(hsql);
          entityManager.flush();
          Integer result = query.executeUpdate();
          entityManager.clear();
          return result;
      }
  
  }
  </code></pre>
  
  <p>This approach works similar to <code>@Modifying(clearAutomatically = true)</code> but it first forces the EntityManager to flush all changes to DB before executing the update and then it clears the persistence context. This way there won't be outdated entities and all changes will be saved in DB.</p>
  
  <hr>
  
  <p>I would like to know if there's a better way to execute update statements in JPA without having the issue of the outdated entities and without the manual flush to DB. Perhaps disabling the 2nd level cache? How can I do it in Spring Boot?</p>
  
  <hr>
  
  <p><strong>Update 2018</strong></p>
  
  <p>Spring Data JPA approved my PR, there's a <code>flushAutomatically</code> option in <code>@Modifying()</code> now.</p>
  
  <pre class="lang-java prettyprint-override"><code>@Modifying(flushAutomatically = true, clearAutomatically = true)
  </code></pre>