I have a web app. If i make a change to the database not using the application (command line), my entities dont show this change.
Is there a way I can make the entities aware that the data has changed and they need to update?
I have a web app. If i make a change to the database not using the application (command line), my entities dont show this change.
Is there a way I can make the entities aware that the data has changed and they need to update?
Although probably not the most elegant solution, you could try calling refresh()
on the entity manager. See this answer: Java JPA - Sync Database and Entity
Alternatively, you could use pessimistic locks to prevent the data changing unexpectedly while using your entities.
JPA is not a database observer, as well as the underlying JDBC isn't one. There is no method of being notified from the database server that some of your entities contain old or inexistent data. The only way of knowing is refreshing or trying to commit the current transaction.
Your problem is that you are using resource-local transaction type. You are obliged to design your transaction begin() and commit() - technically named transaction demarcation. If the EntityManager is held too long it can lead to stale data - like in your complaint - or even memory leaks and poor performance. You have to work out your own transaction management policy.
On the other hand, you can spare the headache by developing for an application server like GlassFish, a JTA transaction type will be created for a thread-safe EntityManager which is typically injected by the server. Thus you are saved all the transaction plumbing.
My argument refers to the JSR-317 JPA specification following quotation from page 294:
A new persistence context begins when the container-managed entity manager is invoked in the scope of an active JTA transaction ... The persistence context is created and then associated with the JTA transaction. The persistence context ends when the associated JTA transaction commits or rolls back, and all entities that were managed by the EntityManager become detached.
Please refer to my answer in this post for the steps to setup a JTA transaction type in GlassFish.
In case you need to give priority to DB updates done outside your application over updates in your current EntityManager - meaning JTA transaction - operations. Then use EntityManager.refresh() method which discards your current non-finished transaction operations till the refresh() call and resorts to the DB latest state.