0

I use JPA (EclipseLink). I have entity class

@Entity
@Table(name = "my_table")
public class MyEntity implements java.io.Serializable {    
  @Id
  @Column(name = "id")
  int id;    
  @Column(name = "name")
  String name;    
  @Lob
  @Column(name = "data")
  byte[] bytes;
  //getters und setters are ommited
}

And I have such query

Query query = entityManager.createQuery("SELECT m FROM MyEntity m WHERE m.name = :name");

After I get result first time, data field in database changed. But when I run this query next times I still get old value. Can anybody explain me such behavior and show me a way how to get updated value

UPD: I call query.getResultList() and get instance of MyEntity. Then other application changes data in DB and commit it (I can run sql statement and I see it's really commited). Then I call query.getResultList() again and get instance of MyEntity that contains old data. My application uses transaction isolation level TRANSACTION_READ_COMMITTED. I've checked this by

Connection c = entityManager.unwrap(Connection.class);
c.getTransactionIsolation();

UPD2: I've noticed that when I invoke the above statement entityManager.unwrap(Connection.class) the behavior is like cache cleared after this call. After this call I get updated instance by calling query.getResultList(). I'm totally confused about this.

Joel
  • 473
  • 2
  • 7
  • 22
  • You will need to show how the data changes and when (relative to your repeated queries), because your problem is probably related to transaction management. In other words: the change to your data probably hasn't been written to the database. – blagae Sep 18 '14 at 14:27
  • I just fixed a caching problem in my app. I am pretty sure you have the same issue. Review the JPA caching - helps a lot. – Jama Djafarov Sep 18 '14 at 14:57
  • Do you call first and second query from inside the same entityManager or from 2 different entityManagers? Remember of cache Level 1 that is used implicitly. – przemek hertel Sep 18 '14 at 15:14
  • From the same entityManager – Joel Sep 19 '14 at 07:11
  • So unless your UPD2 has a performance hit that is significant enough to impact your project, you've likely found your solution – blagae Sep 19 '14 at 07:15
  • I don't understand why this action entityManager.unwrap(Connection.class) results in clearing cache – Joel Sep 19 '14 at 07:28
  • If you really want to know, go into the EclipseLink sources (you can download them if they're not available in your IDE) and then debug the EntityManagerImpl class: there is an explicit check "if (cls.equals(java.sql.Connection.class))" – blagae Sep 19 '14 at 10:10

2 Answers2

0

Since there's another application changing the data, your cache is outdated. Therefore, your question is essentially a duplicate of: EntityManager doesn't see changes made in other transactions

Please try the suggestions made in the accepted answer there, and see what that does for your problem.

EDIT: clearing the cache is usually vendor-dependent, so you'll have to search for documentation for your provider. For EclipseLink, this looks promising: http://wiki.eclipse.org/EclipseLink/Examples/JPA/Caching#How_to_refresh_the_cache

EDIT2: Since you use the EntityManager, you could try this directly:

em.getEntityManagerFactory().getCache().evictAll();
Community
  • 1
  • 1
blagae
  • 2,342
  • 1
  • 27
  • 48
0

If you don´t want an entity to be cached you can try to mark it as not cacheable: @Cacheable(false)

@Entity
@Table(name = "my_table")
@Cacheable(false)
public class MyEntity implements java.io.Serializable { 
marcoslop
  • 106
  • 7