1

I am quite new to hibernate and I was learning about first-level caching in hibernate. I have a concern in first level cache consistency.

Imagine I have two separate Web Applications which can read/write to the same database. Both applications use hibernate. First application consists following code segment.

//First Application code 
//Open the hibernate session
Session session = HibernateUtil.getSessionFactory().openSession();
session.beginTransaction();

//fetch the client entity from database first time
Client client= (Client) session.load(Client.class, new Integer(77869));
System.out.println(client.getName());

//execute some code which runs for several minutes

//fetch the client entity again
client= (Client) session.load(Client.class, new Integer(77869));
System.out.println(client.getName());
session.getTransaction().commit();

The second application consists of the following code.

//Second Application code 
//Open the hibernate session
Session session = HibernateUtil.getSessionFactory().openSession();
session.beginTransaction();

//fetch the client entity from database first time
String hql = "UPDATE client set name = :name WHERE id = :client_id";
Query query = session.createQuery(hql);
query.setParameter("name", "Kumar");
query.setParameter("client_id", "77869");
int result = query.executeUpdate();
System.out.println("Rows affected: " + result);
session.getTransaction().commit();

Let's say the first application creates the session at 10.00 AM. the first application keeps that session object live for 10 minutes. Meanwhile, at 10.01AM second application do an update to Database (update CLIENT set name = 'Kumar' where id = 77869).

So first level cache in first application is outdated after 10.01AM. am I right? if so, is there any method to avoid this scenario?

Maciej Kowalski
  • 25,605
  • 12
  • 54
  • 63
  • According to [this website](https://javarevisited.blogspot.com/2012/07/hibernate-get-and-load-difference-interview-question.html), simply use `session.get()` instead of `session.load()` to ensure an up to date state for the object – XtremeBaumer Aug 01 '19 at 06:13
  • I understood. By the way am I right to say cache getting outdated in my scenario? – Nimash Dilanka Aug 01 '19 at 07:01
  • This may help https://stackoverflow.com/questions/18721634/hibernate-first-level-cache-does-it-sync – Robert Ellis Aug 01 '19 at 08:13

1 Answers1

0

There is no implicit way your first application will know about the underlying changes that were triggered by the second application.

One of the possible ways to handle this situation could be the following:

1) Once one of the applications does update / insert it needs to save a flag of some sort in the database for example that the data has been changed.

2) In the other application you just after you start a new session you need to check whether that flag is set and therefore the data has been altered.

If so, you need to set the CacheMode of the session accordingly:

session.setCacheMode(CacheMode.REFRESH);

This would ensure that during this session all the queried entities will not be taken from the cache but from the DB (therefore updating the cache in the process). Most likely this will not update all the changes in the second-level change, you would need to set that session attribute periodically every now and then.

Keep in mind that second-level-caching anything else than dictionary entities that do not really change is tricky in terms of consistency.

Maciej Kowalski
  • 25,605
  • 12
  • 54
  • 63