1

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?

user489041
  • 26,050
  • 52
  • 126
  • 198
  • This is because JPA uses a cache. If you restart your app server, the changes will be detected. – jahroy Nov 16 '12 at 22:27
  • @jahroy is there a way to force all the entities to update? – user489041 Nov 16 '12 at 22:28
  • I'm sure there are ways to configure the way JPA uses caching. You'll have to research that. I doubt there's a (simple) way to send a message to JPA to update its cache from your database client. Here's a related question that might get you started: http://stackoverflow.com/q/2809275/778118 – jahroy Nov 16 '12 at 23:14

3 Answers3

0

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.

Community
  • 1
  • 1
Kevin
  • 3,790
  • 3
  • 42
  • 65
0

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.

MaDa
  • 10,016
  • 5
  • 39
  • 81
  • This is true, but isn't it possible to configure JPA such that it does not use a cache? – jahroy Nov 17 '12 at 02:22
  • 1
    @jahroy That's provider dependent. JPA as a specification does not say anything about caching, it leaves that to implementors. – MaDa Nov 17 '12 at 20:46
0

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.

One tip

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.

Community
  • 1
  • 1
Sym-Sym
  • 3,356
  • 1
  • 27
  • 29