I have Hibernate with 2nd level cache provided by Ehcache.
I have Parent
and Child
classes, with Parent.children
cached collection.
When I execute the following code:
Session session = DataSessionFactory.openSession();
Transaction tx = session.beginTransaction();
Parent parent = // load from Session
Child child = new Child();
child.setParent(parent);
session.saveOrUpdate(child);
session.flush();
session.refresh(parent);
tx.rollback();
session.close();
session = DataSessionFactory.openSession();
tx = session.beginTransaction();
parent = session.load(Parent.class, parent.getId());
System.out.println(parent.getChildren());
The last line fails with an exception, trying to load Child
which does not exist. After investigation I found the reason is that it's trying to load Child
which have been created and rolled back in the previous transaction.
What is the correct way to configure caching, or roll back the transaction, so that collection cache is cleared properly? I don't want to purge all collection caches on rollback, thank you. Looking for a way to make Hibernate or Ehcache do it for me with minimal impact.
The Hibernate transaction manager is quite simple and from what you described, it seems it doesn't handle this case. The reason is simple: Hibernate is not trying to implement JTA by itself, as there are plenty of JTA providers out there. So, if you are using an application server like JBoss AS, you can configure Hibernate and EHCache to use its JTA provider, which would certainly handle this situation.
Also, I believe that the entity is being put into the cache by the "flush" method. So, if you don't want to use a JTA provider and unless this "flush" is really needed, I'd remove that part.