Note that there are some explanatory texts on larger screens.

plurals
  1. POJPA / Eclipselink @Cache expiry ignored
    text
    copied!<p>I'm currently evaluating JPA/Eclipselink as an alternative to our current very ugly jdbc database access. The situation is the following:</p> <p>Multiple clients access the same database and sometimes edit the same data. This data should be refreshed regularly and only be cached for a short period of time. From my understanding the @Cache annotation should exactly do that.</p> <p>The following code is based on the jpa/eclipselink on <a href="http://www.vogella.com/articles/JavaPersistenceAPI/article.html" rel="nofollow">Vogella</a></p> <pre><code>@Entity @Cache(expiry = 100) public class Todo { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String summary; private String description; ... getter/setter/toString omited } public static void main(String[] args) throws InterruptedException { EntityManagerFactory factory = Persistence.createEntityManagerFactory("mysql"); EntityManager em = factory.createEntityManager(); TypedQuery&lt;Todo&gt; q = em.createQuery("SELECT t FROM Todo t", Todo.class); List&lt;Todo&gt; todoList = q.getResultList(); System.out.println("Query 1 read"); for (int i = 0; i &lt; todoList.size(); i++) { System.out.println("1: " + todoList.get(i)); } Thread.sleep(30000); TypedQuery&lt;Todo&gt; q2 = em.createQuery("SELECT t FROM Todo t", Todo.class); // q2.setHint("javax.persistence.cache.storeMode", "REFRESH"); List&lt;Todo&gt; todoList2 = q2.getResultList(); System.out.println("Query 2 read"); for (int i = 0; i &lt; todoList.size(); i++) { System.out.println("1: " + todoList.get(i)); System.out.println("2: " + todoList2.get(i)); System.out.println(todoList.get(i) == todoList2.get(i)); } } &lt;?xml version="1.0" encoding="UTF-8"?&gt; &lt;persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"&gt; &lt;persistence-unit name="mysql" transaction-type="RESOURCE_LOCAL"&gt; &lt;provider&gt;org.eclipse.persistence.jpa.PersistenceProvider&lt;/provider&gt; &lt;exclude-unlisted-classes&gt;false&lt;/exclude-unlisted-classes&gt; &lt;properties&gt; &lt;property name="javax.persistence.jdbc.password" value="" /&gt; &lt;property name="javax.persistence.jdbc.user" value="root" /&gt; &lt;property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver" /&gt; &lt;property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/test" /&gt; &lt;property name="javax.persistence.ddl-generation" value="create-tables" /&gt; &lt;property name="javax.persistence.logging.level" value="ALL" /&gt; &lt;property name="eclipselink.logging.level" value="ALL"/&gt; &lt;/properties&gt; &lt;/persistence-unit&gt; &lt;/persistence&gt; </code></pre> <p>Running the Programm produces the following output:</p> <pre><code>... [EL Finest]: query: 2013-06-19 14:30:55.897--UnitOfWork(31211079)--Thread(Thread[main,5,main])--Execute query ReadAllQuery(referenceClass=Todo sql="SELECT ID, DESCRIPTION, SUMMARY FROM TODO") [EL Finest]: connection: 2013-06-19 14:30:55.907--ServerSession(7427424)--Connection(7633596)--Thread(Thread[main,5,main])--Connection acquired from connection pool [default]. [EL Fine]: sql: 2013-06-19 14:30:55.907--ServerSession(7427424)--Connection(7633596)--Thread(Thread[main,5,main])--SELECT ID, DESCRIPTION, SUMMARY FROM TODO [EL Finest]: connection: 2013-06-19 14:30:55.924--ServerSession(7427424)--Connection(7633596)--Thread(Thread[main,5,main])--Connection released to connection pool [default]. Query 1 read 1: Todo [id=1, summary=s1, description=d1] 1: Todo [id=2, summary=qwet, description=d2] [EL Finest]: query: 2013-06-19 14:31:25.932--UnitOfWork(31211079)--Thread(Thread[main,5,main])--Execute query ReadAllQuery(referenceClass=Todo sql="SELECT ID, DESCRIPTION, SUMMARY FROM TODO") [EL Finest]: connection: 2013-06-19 14:31:25.932--ServerSession(7427424)--Connection(7633596)--Thread(Thread[main,5,main])--Connection acquired from connection pool [default]. [EL Fine]: sql: 2013-06-19 14:31:25.932--ServerSession(7427424)--Connection(7633596)--Thread(Thread[main,5,main])--SELECT ID, DESCRIPTION, SUMMARY FROM TODO [EL Finest]: connection: 2013-06-19 14:31:25.934--ServerSession(7427424)--Connection(7633596)--Thread(Thread[main,5,main])--Connection released to connection pool [default]. Query 2 read 1: Todo [id=1, summary=s1, description=d1] 2: Todo [id=1, summary=s1, description=d1] true 1: Todo [id=2, summary=qwet, description=d2] 2: Todo [id=2, summary=qwet, description=d2] true </code></pre> <p>While the Thread sleeps I change a value in the database. I would expect to get the new value from the database, because the value in the cache should have been expired. It seems the code simply ignores the @Cache annotation. I also tried various other settings like type=CacheType.NONE und alwaysRefresh=true, but none did change anything.</p> <p>When I add the storeMode-QueryHint, the query always refreshes the result. This is not exactly what I want and it seems I need to add it to each query which is quite error prone. But it is still strange that the Cache annotation is ignored.</p> <p>I also tried to use a DescriptorCustomizer, but it also has no effect, despite being used (tested with a breakpoint).</p> <pre><code>public void customize(ClassDescriptor descriptor) { descriptor.alwaysRefreshCache(); descriptor.alwaysRefreshCacheOnRemote(); descriptor.disableCacheHits(); descriptor.disableCacheHitsOnRemote(); } </code></pre> <p>Update:</p> <p>Some words to the system I'm developing. It's module to read/write our master data. Therefore, it feels wrong to have, for example, an User-object twice in memory for the same user. Also after I tested the @ReadOnly annotation I noticed that the isolation-parameter of the @Cache annotation seems to work, but still nothing about the expire, alwaysrefresh, etc.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload