Reputation: 9139
My applications very often queries database for rarely-changed data. So I've decided to optimize it using cached EJB entities as desribed in: http://docs.jboss.org/ejb3/docs/tutorial/1.0.7/html/Caching_EJB3_Entities.html
However, when I take a look at hibernate sql logs (hibernate.show_sql = true) I can still see the same number of queries hitting database as without cache configured. Here is my persistence.xml file:
<persistence 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_1_0.xsd"
version="1.0">
<persistence-unit name="myds">
<jta-data-source>java:/myds</jta-data-source>
(...) classes definitions
<class>com.my.class.MyEntityOne</class>
(...)
<properties>
<property name="hibernate.show_sql" value="true" />
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect"/>
<property name="hibernate.format_sql" value="false" />
<property name="hibernate.hbm2ddl.auto" value="update"/>
<property name="hibernate.transaction.manager_lookup_class" value="org.hibernate.transaction.JBossTransactionManagerLookup"/>
<property name="hibernate.transaction.factory_class" value="org.hibernate.ejb.transaction.JoinableCMTTransactionFactory"/>
<!-- 2nd level cache -->
<property name="hibernate.cache.use_second_level_cache" value="true"/>
<property name="hibernate.cache.use_query_cache" value="true"/>
<property name="hibernate.cache.region.factory_class" value="org.hibernate.cache.jbc2.JndiMultiplexedJBossCacheRegionFactory"/>
<property name="hibernate.cache.region.jbc2.cachefactory" value="java:CacheManager"/>
<property name="hibernate.cache.region.jbc2.cfg.entity" value="mvcc-entity"/>
<property name="hibernate.cache.region.jbc2.cfg.query" value="local-query"/>
</properties>
</persistence-unit>
All my JPA entities are annotated with:
@Cache (usage=CacheConcurrencyStrategy.TRANSACTIONAL)
Maybe a little hint will be that when I shut down server the following exception can be seen in logs:
org.hibernate.cache.CacheException: java.lang.IllegalStateException: Cache not in STARTED state! at org.hibernate.cache.jbc2.BasicRegionAdapter.destroy(BasicRegionAdapter.java:243) at org.hibernate.impl.SessionFactoryImpl.close(SessionFactoryImpl.java:813) at org.hibernate.ejb.EntityManagerFactoryImpl.close(EntityManagerFactoryImpl.java:46) at org.jboss.jpa.deployment.ManagedEntityManagerFactory.destroy(ManagedEntityManagerFactory.java:93) at org.jboss.jpa.deployment.PersistenceUnitDeployment.stop(PersistenceUnitDeployment.java:343) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597)
Should I do some additional setup? Any help is appreciated!
Thanks in advance, Piotr
Upvotes: 2
Views: 1444
Reputation: 9139
Caching queries (as skaffman suggested):
Query query = manager.createQuery("SELECT i FROM ....");
query.setHint("org.hibernate.cacheable", true);
In case of entities, I noticed, that it not enough to annotate all entities with @Cache. If your entity has reference to other entities (annotated with @Cache), you must also include this annotation on a top of a referencing field:
@Cache (usage=CacheConcurrencyStrategy.TRANSACTIONAL)
@Entity
public class EntityA {
@Cache (usage=CacheConcurrencyStrategy.TRANSACTIONAL)
private Set<EntityB> entitiesB;
}
@Cache (usage=CacheConcurrencyStrategy.TRANSACTIONAL)
@Entity
public class EntityB {
}
I don't know if it's general rule, but in my case, after I've added these annotations, everything started to work as expected.
Upvotes: 1