I have a minimal web app that you can download here (6Kb): http://www.mediafire.com/?6vo1tc141t65r1g
the relevant config is :
-eclipselink 2.3.2
-server is tomee 1.0 (but glassfish 3.1 is the same)
When I hit the page and press F5 to refresh repeatedly :
http://localhost:8080/testCache/jsf/test.xhtml
I see several lines like that in the console
[EL Fine]: 2012-08-29 19:01:30.821--ServerSession(32981564)--Connection(27242067)--Thread(Thread[http-bio-8080-exec-12,5,main])--SELECT id, tasktype FROM tasktype
And by running a sniffer I see that SQL requests are always sent to the server. I though the level 2 cache of Eclipselink would return the results (5 rows in a table) without querying the db. So what's wrong, how do I activate the cache ?
Some extracts from the files
persistence.xml :
<?xml version="1.0" encoding="UTF-8"?>
<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">
<persistence-unit name="xxxPU" transaction-type="JTA">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<jta-data-source>microsoft</jta-data-source>
<properties>
<property name="eclipselink.logging.level" value="FINE"/>
<property name="eclipselink.logging.parameters" value="true"/>
</properties>
</persistence-unit>
</persistence>
the EJB performing the query
/**
* Some useless class required to use JTA transactions
*
* @author Administrator
*
*/
@Stateless
public class Facade {
@PersistenceContext(unitName = "xxxPU")
private EntityManager em;
public List findAll(Class entityClass) {
CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
cq.select(cq.from(entityClass));
return em.createQuery(cq).getResultList();
}
public EntityManager getEntityManager() {
return em;
}
}
the entity bean :
@Entity
@Table(name = "tasktype")
public class TaskType {
@Id
@Column(name = "id")
private Integer id;
@Basic(optional = false)
@NotNull
@Size(min = 1, max = 10)
@Column(name = "tasktype")
private String name;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
The L2 shared cache, caches objects by there Id. The find() operation, and queries by Id will obtain cache hits, other queries will not. The resulting objects will still be resolved with the cache, so you will not encure any additional queries for relationships once the objects are cached.
You can enable caching on a query, or (in 2.4) you can index non-Id fields, or query in-memory.
See, http://wiki.eclipse.org/EclipseLink/UserGuide/JPA/Basic_JPA_Development/Caching
http://wiki.eclipse.org/EclipseLink/UserGuide/JPA/Basic_JPA_Development/Caching/Query_Cache
http://wiki.eclipse.org/EclipseLink/UserGuide/JPA/Basic_JPA_Development/Caching/Query_Options