Sunday 28 June 2015

What does EntityManager.clear() do?

It clears L1 cache. 

See an example
 
@Transactional
public void test(){
   Book book = bookDao.findById(1);
   System.out.println("Old Author: "+book.getAuthor());
   bookDao.updateBookAuthor(1, "New author");
   book = bookDao.findById(1);
   System.out.println("New Author: "+book.getAuthor());
}

The output is
Old Author: Old Author
New Author: Old Author

Line 1, JPA loads the Book entity from database and saves it into L1 cache.
Line 3 is a JPQL bulk update statement:

update Book b set b.author = :author where b.id = :id

It changes the entity's author and stores it into L2 cache, while the entity at L1 cache is unchanged.

Line 4, JPA loads the entity from L1 cache and therefore still shows the old author value.

Now check the changes that the clear() method brings.


@Transactional
public void test(){
   Book book = bookDao.findById(1);
   System.out.println("Old Author: "+book.getAuthor());
   bookDao.updateBookAuthor(1, "New author");
   entityManager.clear();
   book = bookDao.findById(1);
   System.out.println("New Author: "+book.getAuthor());
}

The output is
Old Author: Old Author
New Author: New Author

EntityManager.clear() clears the L1 cache so that at line 5, JPA has to load the entity from L2 cache.

So the clear() method doesn't clear any changes made to the entity. Namely, all the changes will still be committed to database. It does nothing more than just clearing the L1 cache.