hibernatejpaspring-boothibernate-cache

Hiberanate disable cached results


My Application has a service will polls internally for job output. It polls till the job status changes from "In-progress" to "Completed". Another system is going to update the job status to "Completed" once it processes the job.

The problem here is, first time when the job status is polled from DB the status as "In-progress". But later even when the job status is changed by other process I still see it as "In-progress". The issue is not with DB Isolation level(Repeatable Read) as my hibernate queries are executing out of transaction. I suspect the results are cached and when same query is executed in the same session, I'm getting the cached results.

How can I get the updated data from DB when same query is executed in same session multiple times.

Regards, Chandu


Solution

  • UPDATE

    As per the comments, it is a Spring Boot application that uses Spring JPA data. And the service class checks for the status every 5 minutes with a loop in it. i.e., which effectively is in a same transaction i.e., same session.

    And so, unless we call refresh() or evict() and reload we won't be able to see the updated state from the database.

    But the problem is that the CrudRepository doesn't expose any methods like refresh() that we can call on entity manager.

    So the option is to the CrudRepository and add a method say refreshEntity(...). This method will internally call entityManager.refresh(). Finally the service loop can invoke this refreshEntity(..) method and get the updated data.

    As an example:

    public interface MyStatusRepository {
       void refreshEntity(StatusEntity se);
    }
    
    public interface StatusRepository extends CrudRepository<StatusEntity, Long>, MyStatusRepository {
        ...
    }
    
    @Repository
    public class MyStatusRepositoryImpl implements MyStatusRepository {
        @PersistenceContext
        private EntityManager entityManager;
    
        @Override
        public void refreshEntity(StatusEntity se); {
            entityManager.refresh(se);
        }
        ...
    }
    

    More information on Extending repository can be found at the above link.

    Other option was, instead of extending the CrudRepository, autowire the entityManager in the service class itself and call the refresh() on it. This works as well, but would be a deviation from the existing design.