0

I'd like to access the persistence layer through JPA/Eclipselink and JDBC Connections in the same application.

The problem is, that changes which have been made directly using the JDBC Connections aren't reflected to the JPA EntityManagers, even though I open the newly created EntityManager afterwards.

I'm using Tomcats JDBC-Connection pool for both, the JDBC Connections and the JPA EntityManagers.

Is there a way to handle such "conflicts"? I've found this: Disable caching in JPA (eclipselink).

I've also found this: http://wiki.eclipse.org/EclipseLink/Examples/JPA/EMAPI#Getting_a_JDBC_Connection_from_an_EntityManager but I don't like the idea, because the code which uses JDBC-Connections is in a seperate library which shouldn't use JPA at all.

Is there a state of the art solution for working likewise with JDBC-Connections and JPA/Eclipselink-Connections?

Community
  • 1
  • 1
kalamar
  • 823
  • 9
  • 19

2 Answers2

1

Have you tried disabling the shared cache? JPA allows two levels of caching - at the factory (shared) level and within the EM itself to hold onto managed entities. If you are making changes outside JPA, you will need to take these caches into account. Using the connection from JPA will not fix this, as it still has no hooks into JPA's caches. So changes outside the EM will only be seen if the em is cleared or the entities involved in the changes are refreshed.

I would use http://wiki.eclipse.org/EclipseLink/Examples/JPA/Caching and the http://wiki.eclipse.org/EclipseLink/UserGuide/JPA/Basic_JPA_Development/Caching link provided by James' answer in the stack overflow question as references.

Using JDBC in the same app is essentially the same as if you were making changes in a different app, except that the JPA application might have more control and knowledge about the changes made, allowing specific invalidation or refreshes to occur. So while disabling the shared cache might be the easiest/quickest solution, EclipseLink invalidation and targeted refreshes might allow still getting the benefits of caching.

Chris
  • 17,615
  • 1
  • 26
  • 38
0

I'd like to anwser my own question.

In my case I have a sequence of operations like this:

  1. Work with a JPA EntityManager
  2. Work with a JDBC Connection
  3. Work with a JPA EntityManager

In the scenario above, one may work on invalid data in step 3.

Here is a working sequence of operations:

  1. Work with a JPA EntityManager
  2. Close the EntityManager
  3. Work with a JDBC Connection
  4. Close the JDBC Connection
  5. Create a new JPA EntityManager
  6. Refresh all caches: em.getEntityManagerFactory().getCache().evictAll(); (1)
  7. Work with a JPA EntityManager

In this special sequence of operations (it's different when one have to work in a concurrent environment) it's better than disabling the cache for the whole application.

For a more general anwser to this question see Chris anwser above.

(1) http://wiki.eclipse.org/EclipseLink/Examples/JPA/Caching

kalamar
  • 823
  • 9
  • 19
  • @Chris and others: Do you know how to handle this sequence in a transacction? – kalamar Nov 14 '13 at 17:08
  • 1
    If you are using a JTA datasource, then steps 1-3 will be in the same transaction and you only need to call em.flush at end of step 1 to get it to write out changes early. If not in JTA, you will need to make sure they all use the same connection with a transaction started for all 3 steps. Probably using the em to get and start a transaction, and getting the connection from the em to use in step 2, then reusing the same em (flushed at end of step 1 still) but clearing it so it can see changes from step 2 – Chris Nov 14 '13 at 21:23