views:

1137

answers:

3

I am using an EXTENDED Persistent Context because it will allow me to Lazily Load a one-many relationship on an object and it also won't require a SELECT before I "merge" an object with the persistent context.

I have an DummyObject with:

  1. A "Last Updated" Date Field

  2. A One-Many Relationship

This Object is being updated every 5 seconds in one JVM through a em.merge(DummyObject) call.

In another JVM, I query for the DummyObject doing a call like the following

em.createQuery("from DummyObject").getResultList();

I am also doing this Query every 5 seconds.

The problem is, is that the Objects resulted from the Query all have a Timestamp of the very first Query after successive calls, even though Hibernate is generating the correct SQL statement (when I have statement logging on), and the Database is getting the updates correctly (I have verified).

I have also tried all sorts of optimistic locking with @Version to no avail. (See comments)

Another thing is that this does work correctly when:

  1. I change the PersistentContextType to TRANSACTIONAL (something that will not allow me to lazily load the ONE-MANY relationship)

  2. I do an EntityManager.clear() call before I do the Query above (Something that will also not allow me to lazily load the ONE-MANY relationship).

Why does my Query return stale data? I have no Second Level Caching or Query Caching enabled.

Am I doing something wrong? Is there something I can set through query.setHint( , )?

Maybe I don't understand "EXTENDED" vs TRANSACTIONAL correctly.

A: 

Have you tried doing a flush() before your fetch?

Jesse
Just tried that... Didn't work. Thanks though.
Grasper
Are you re-fetching the object every time, or using the lazy loaded reference? I've had issues where the object needed to be fetched again before new data showed up.
Jesse
I'm not sure if I understand what you mean. I am executing the Query above every 5 seconds, and the results I get from that Query are stale. This is more of a "test" case than an actual implementation. Basically what my problem is, is that I want to be able to use the EXTENDED context type and be able to lazily load relationships. But what is not working is that the Query always returns stale results.
Grasper
Something like: HibObj o = oDao.get(o.getId());
Jesse
A: 

Interesting. To me it seems that the entity instance in your persistence context is not updated with the results from the query. This might be by design - you could accidentally overwrite local changes by executing a query.

What's worse is that there is no way in JPA to detach a single instance. You either clear the entire context or you don't. So that is not a possible solution either.

There is a refresh() method available in the PersistanceContext class that grabs changes from the database and updates the entity instance accordingly. But I can see how that might not be applicable in an actual implementation. So my answer turns out to be: you probably can't get it to work.

waxwing
Yeah, I've looked at iterating through the returned result set and doing a "refresh" on each object, but that gets ridiculous with large result sets.
Grasper
Does the content of the list stay the same (i.e., will you not get new objects, or old objects deleted)?
Jack Leow
The content of the list stays the same if I do not do a refresh() on each object in the list.
Grasper
+1  A: 

The hibernate session is caching the persistent objects. So because you are modifying in one JVM (A) and reading in another JVM(B), B's sessions needs to be refreshed to see the changes. You could open a new session or evict/refresh the persistent objects. You can also replicate the sessions across both JVMs which might take care of your problem. Or you could try changing the query to only return pieces of the 'DummyObject' which you need and only read the persistent object when it is required. You might also try a stateless session.

ccclark