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
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.