0 Replies Latest reply on Nov 12, 2012 10:26 AM by phoenix7360

    JBoss AS 7.1.1 + JPA + Infinispan

    phoenix7360

      Background:

      I am developping a web application  in Java EE 6, using JBoss AS 7.1.1 and JPA (using the Hibernate Implementation). At the moment I'm running JBoss in standalone mode.

       

      I saw that Infinispan was packaged with JBoss AS 7.1.1 and I thought I could have a go. What I'm trying to achieve here is to use Infinispan in the most simple way, in order to save time on database lookups.

       

      To give you a concrete example, I have a company structure that looks something like that: Company->Division->BusinessUnit (-> representing a Many-to-One relationship. For example a company has many Division etc..). These objecs are persisted using JPA annotations and everything is working fine. However, because my dataset has grown quite a bit, queries on the database start to take a signifcant amount of time. For example, I have a set of statistics that need to get the whole tree of data starting from Company, several time in a row. I first wrote my own cache (which was storing the Company object in a Hash-Map) and then realised I should leave the complex task of caching to JPA and Hibernate. The objects are not heavy in themselves, it just that I have many of them at each leven of the tree.

       

      My Infinispan configuration:

      I have read a lot of tutorials and post on this forum but I'm still not sure to have it right.

       

      1) I have added the JPA @Cachable annotations to my Company, Division, BusinessUnit classes.

       

      2) I have updated my persistence.xml using:

       

      <property name="hibernate.cache.use_second_level_cache" value="true" />
      <property name="hibernate.cache.use_query_cache" value="true" />
      <property name="hibernate.cache.infinispan.cachemanager" value="java:jboss/infinispan/container/hibernate" />
      

       

      3)I have created a "Resource Singleton Bean"

       

      @Singleton
      public class Resources {
      
         @Produces
         @Resource(name="java:jboss/infinispan/container/hibernate")
         private static EmbeddedCacheManager container;
      }
      

       

      4)Added the follwing depency to my pom.xml (still not sure if it is needed)

       

      <dependency>
           <groupId>org.infinispan</groupId>
           <artifactId>infinispan-core</artifactId>
           <version>5.1.4.FINAL</version>
           <scope>provided</scope>
      </dependency>
      <dependency>
           <groupId>org.infinispan</groupId>
           <artifactId>infinispan-cdi</artifactId>
           <version>5.1.4.FINAL</version>
      </dependency>
      
      

       

      5)In my standalone.xml I have :

       

           <subsystem xmlns="urn:jboss:domain:infinispan:1.2" default-cache-container="hibernate">
                  <cache-container name="hibernate" default-cache="local-query" jndi-name="java:jboss/infinispan/container/hibernate">
                      <local-cache name="entity">
                          <transaction mode="NON_XA"/>
                          <eviction strategy="LRU" max-entries="10000"/>
                          <expiration max-idle="100000"/>
                      </local-cache>
                      <local-cache name="local-query">
                          <transaction mode="NONE"/>
                          <eviction strategy="LRU" max-entries="10000"/>
                          <expiration max-idle="100000"/>
                      </local-cache>
                      <local-cache name="timestamps">
                          <transaction mode="NONE"/>
                          <eviction strategy="NONE"/>
                      </local-cache>
                  </cache-container>
              </subsystem>
      
      

       

       

      Using this, my webapplication deploys on JBoss and I get a few lines of loggin suggesting that Infinispan is running.

       

      However I cannot see any performance improvment.

      In order to try to figure out if entities were being cached I created a simple Arquilian JUnit test: I save an arbitrary entity (having the @Cacheable annotation) into the DB (JBoss in-memory database). Then I perform two select on this object. Using

       

      <property name="hibernate.cache.use_second_level_cache" value="true" />
      

       

      in my persistence.xml, I check what SQL is being called. I get one insert and two selects. If I understand correctly how a 2nd Level Cache should work, I shouldn't get the second select (and even the first one if the entity can be cached during the insert).

       

      My questions:

      1) I'd like to know if my Infinispan configurations makes sense. Do I need something extra than the @Cacheable annotations and the few configuration lines in the percistene.xml?

      2) How can I tell if entities are being cached? Does my Unit Test make sense?

      3) Even though it is clearly stated that 2nd Level cache may not improve the performance, I'm still surprised that I cannot see any difference. The JBoss documentation states that there are different types of caching (Entity, Collection, Query, Time Stamp). Could the lack of improvement be explained by the fact that what I really need is caching of collections and my Infinispan configuration is only caching entities? How could I enforce caching of collections?

       

      Many thanks in adance.