8 Replies Latest reply on Sep 23, 2014 12:34 PM by hamzabenmansour

    JPA cache store - JBoss AS 7 JTA configuration

    palov

      What is the correct configuration of the Infinispan cache with JPA store on JBoss AS 7?

       

      If I don't configure the hibernate.transaction.manager_lookup_class explicitly in persistence.xml, Infinispan doesn't find the transaction manager.

      When I do I get an *java.lang.IllegalStateException: A JTA EntityManager cannot use getTransaction()*, when I try to put an Entity into the cache.

       

      Am I missing something? I would appreciate any working example.

       

       

      h5. My configuration:

       

      *- JBoss AS 7.1.1.Final*

      *- Infinispan 5.3.0.CR1 - installed as a JBoss module*

       

      h6. persistence.xml :

      {code}

      <persistence-unit name="myPU" transaction-type="JTA">

           <description>myPU Persistence Unit</description>

           <provider>org.hibernate.ejb.HibernatePersistence</provider>

           <jta-data-source>java:/datasources/myPU</jta-data-source>

           <class>com.model.Test</class>

           <exclude-unlisted-classes>false</exclude-unlisted-classes>

           <properties>

                <property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5InnoDBDialect"/>

                <property name="hibernate.hbm2ddl.auto" value="validate"/>

                <property name="hibernate.show_sql" value="${showSql}"/>

                <property name="hibernate.format_sql" value="true"/>

                <property name="hibernate.ejb.naming_strategy" value="org.hibernate.cfg.ImprovedNamingStrategy"/>

                <property name="hibernate.transaction.manager_lookup_class" value="org.hibernate.transaction.JBossTransactionManagerLookup"/>

           </properties>

      </persistence-unit>

      {code}

       

      h6. Cache configuration:

      {code}

      public void init() {

           Configuration configuration = new ConfigurationBuilder()

                          .loaders().addLoader(JpaCacheStoreConfigurationBuilder.class)

                          .persistenceUnitName("myPU")

                          .entityClass(Test.class)

           .transaction().transactionManagerLookup(new GenericTransactionManagerLookup())

           .build();

       

           DefaultCacheManager cacheManager = new DefaultCacheManager();

           cacheManager.defineConfiguration("jpaCache", configuration);

           jpaCache = cacheManager.getCache("jpaCache");

      }

      {code}

       

      h6. Usage:

      {code}

           public void putIntoCache(byte[] payload) {

                jpaCache.put("name", new Test());

           }

      {code}

       

      h5. Stacktrace:

      {code}

      ...

      Caused by: java.lang.IllegalStateException: A JTA EntityManager cannot use getTransaction()

           at org.hibernate.ejb.AbstractEntityManagerImpl.getTransaction(AbstractEntityManagerImpl.java:996) [hibernate-entitymanager-4.0.1.Final.jar:4.0.1.Final]

           at org.infinispan.loaders.jpa.JpaCacheStore.storeLockSafe(JpaCacheStore.java:370) [infinispan-cachestore-jpa-5.3.0.CR1.jar:5.3.0.CR1]

           at org.infinispan.loaders.jpa.JpaCacheStore.storeLockSafe(JpaCacheStore.java:69) [infinispan-cachestore-jpa-5.3.0.CR1.jar:5.3.0.CR1]

           at org.infinispan.loaders.LockSupportCacheStore.store(LockSupportCacheStore.java:213) [infinispan-core.jar:5.3.0.CR1]

           at org.infinispan.interceptors.CacheStoreInterceptor.visitPutKeyValueCommand(CacheStoreInterceptor.java:242) [infinispan-core.jar:5.3.0.CR1]

           at org.infinispan.commands.write.PutKeyValueCommand.acceptVisitor(PutKeyValueCommand.java:83) [infinispan-core.jar:5.3.0.CR1]

           at org.infinispan.interceptors.base.CommandInterceptor.invokeNextInterceptor(CommandInterceptor.java:120) [infinispan-core.jar:5.3.0.CR1]

           at org.infinispan.interceptors.CacheLoaderInterceptor.visitPutKeyValueCommand(CacheLoaderInterceptor.java:113) [infinispan-core.jar:5.3.0.CR1]

           at org.infinispan.commands.write.PutKeyValueCommand.acceptVisitor(PutKeyValueCommand.java:83) [infinispan-core.jar:5.3.0.CR1]

           at org.infinispan.interceptors.base.CommandInterceptor.invokeNextInterceptor(CommandInterceptor.java:120) [infinispan-core.jar:5.3.0.CR1]

           at org.infinispan.interceptors.EntryWrappingInterceptor.invokeNextAndApplyChanges(EntryWrappingInterceptor.java:290) [infinispan-core.jar:5.3.0.CR1]

           at org.infinispan.interceptors.EntryWrappingInterceptor.visitPutKeyValueCommand(EntryWrappingInterceptor.java:157) [infinispan-core.jar:5.3.0.CR1]

           at org.infinispan.commands.write.PutKeyValueCommand.acceptVisitor(PutKeyValueCommand.java:83) [infinispan-core.jar:5.3.0.CR1]

           at org.infinispan.interceptors.base.CommandInterceptor.invokeNextInterceptor(CommandInterceptor.java:120) [infinispan-core.jar:5.3.0.CR1]

           at org.infinispan.interceptors.locking.AbstractLockingInterceptor.visitPutKeyValueCommand(AbstractLockingInterceptor.java:70) [infinispan-core.jar:5.3.0.CR1]

           at org.infinispan.commands.write.PutKeyValueCommand.acceptVisitor(PutKeyValueCommand.java:83) [infinispan-core.jar:5.3.0.CR1]

           at org.infinispan.interceptors.base.CommandInterceptor.invokeNextInterceptor(CommandInterceptor.java:120) [infinispan-core.jar:5.3.0.CR1]

           at org.infinispan.interceptors.base.CommandInterceptor.handleDefault(CommandInterceptor.java:134) [infinispan-core.jar:5.3.0.CR1]

           at org.infinispan.commands.AbstractVisitor.visitPutKeyValueCommand(AbstractVisitor.java:54) [infinispan-core.jar:5.3.0.CR1]

           at org.infinispan.commands.write.PutKeyValueCommand.acceptVisitor(PutKeyValueCommand.java:83) [infinispan-core.jar:5.3.0.CR1]

           at org.infinispan.interceptors.base.CommandInterceptor.invokeNextInterceptor(CommandInterceptor.java:120) [infinispan-core.jar:5.3.0.CR1]

           at org.infinispan.interceptors.InvocationContextInterceptor.handleAll(InvocationContextInterceptor.java:128) [infinispan-core.jar:5.3.0.CR1]

           at org.infinispan.interceptors.InvocationContextInterceptor.handleDefault(InvocationContextInterceptor.java:92) [infinispan-core.jar:5.3.0.CR1]

           at org.infinispan.commands.AbstractVisitor.visitPutKeyValueCommand(AbstractVisitor.java:54) [infinispan-core.jar:5.3.0.CR1]

           at org.infinispan.commands.write.PutKeyValueCommand.acceptVisitor(PutKeyValueCommand.java:83) [infinispan-core.jar:5.3.0.CR1]

           at org.infinispan.interceptors.InterceptorChain.invoke(InterceptorChain.java:343) [infinispan-core.jar:5.3.0.CR1]

           at org.infinispan.CacheImpl.executeCommandAndCommitIfNeeded(CacheImpl.java:1337) [infinispan-core.jar:5.3.0.CR1]

           at org.infinispan.CacheImpl.putInternal(CacheImpl.java:898) [infinispan-core.jar:5.3.0.CR1]

           at org.infinispan.CacheImpl.put(CacheImpl.java:890) [infinispan-core.jar:5.3.0.CR1]

           at org.infinispan.CacheImpl.put(CacheImpl.java:1390) [infinispan-core.jar:5.3.0.CR1]

           at org.infinispan.CacheImpl.put(CacheImpl.java:229) [infinispan-core.jar:5.3.0.CR1]

        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) [rt.jar:1.7.0_17]

           at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) [rt.jar:1.7.0_17]

           at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) [rt.jar:1.7.0_17]

           at java.lang.reflect.Method.invoke(Method.java:601) [rt.jar:1.7.0_17]

           at org.jboss.as.ee.component.ManagedReferenceMethodInterceptorFactory$ManagedReferenceMethodInterceptor.processInvocation(ManagedReferenceMethodInterceptorFactory.java:72) [jboss-as-ee-7.1.1.Final.jar:7.1.1.Final]

           at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:288) [jboss-invocation-1.1.1.Final.jar:1.1.1.Final]

           at org.jboss.invocation.InterceptorContext$Invocation.proceed(InterceptorContext.java:374) [jboss-invocation-1.1.1.Final.jar:1.1.1.Final]

           at org.jboss.as.weld.ejb.Jsr299BindingsInterceptor.doMethodInterception(Jsr299BindingsInterceptor.java:127) [jboss-as-weld-7.1.1.Final.jar:7.1.1.Final]

           at org.jboss.as.weld.ejb.Jsr299BindingsInterceptor.processInvocation(Jsr299BindingsInterceptor.java:135) [jboss-as-weld-7.1.1.Final.jar:7.1.1.Final]

           at org.jboss.as.ee.component.interceptors.UserInterceptorFactory$1.processInvocation(UserInterceptorFactory.java:36) [jboss-as-ee-7.1.1.Final.jar:7.1.1.Final]

           at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:288) [jboss-invocation-1.1.1.Final.jar:1.1.1.Final]

           at org.jboss.invocation.WeavedInterceptor.processInvocation(WeavedInterceptor.java:53) [jboss-invocation-1.1.1.Final.jar:1.1.1.Final]

           at org.jboss.as.ee.component.interceptors.UserInterceptorFactory$1.processInvocation(UserInterceptorFactory.java:36) [jboss-as-ee-7.1.1.Final.jar:7.1.1.Final]

           at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:288) [jboss-invocation-1.1.1.Final.jar:1.1.1.Final]

           at org.jboss.as.jpa.interceptor.SBInvocationInterceptor.processInvocation(SBInvocationInterceptor.java:47) [jboss-as-jpa-7.1.1.Final.jar:7.1.1.Final]

           at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:288) [jboss-invocation-1.1.1.Final.jar:1.1.1.Final]

           at org.jboss.as.weld.ejb.EjbRequestScopeActivationInterceptor.processInvocation(EjbRequestScopeActivationInterceptor.java:82) [jboss-as-weld-7.1.1.Final.jar:7.1.1.Final]

           at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:288) [jboss-invocation-1.1.1.Final.jar:1.1.1.Final]

           at org.jboss.invocation.InitialInterceptor.processInvocation(InitialInterceptor.java:21) [jboss-invocation-1.1.1.Final.jar:1.1.1.Final]

           at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:288) [jboss-invocation-1.1.1.Final.jar:1.1.1.Final]

           at org.jboss.invocation.ChainedInterceptor.processInvocation(ChainedInterceptor.java:61) [jboss-invocation-1.1.1.Final.jar:1.1.1.Final]

           at org.jboss.as.ee.component.interceptors.ComponentDispatcherInterceptor.processInvocation(ComponentDispatcherInterceptor.java:53) [jboss-as-ee-7.1.1.Final.jar:7.1.1.Final]

           at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:288) [jboss-invocation-1.1.1.Final.jar:1.1.1.Final]

           at org.jboss.as.ejb3.component.pool.PooledInstanceInterceptor.processInvocation(PooledInstanceInterceptor.java:51) [jboss-as-ejb3-7.1.1.Final.jar:7.1.1.Final]

           at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:288) [jboss-invocation-1.1.1.Final.jar:1.1.1.Final]

           at org.jboss.as.ejb3.tx.CMTTxInterceptor.invokeInCallerTx(CMTTxInterceptor.java:202) [jboss-as-ejb3-7.1.1.Final.jar:7.1.1.Final]

           ... 124 more

       

      {code}

        • 1. Re: JPA cache store - JBoss AS 7 JTA configuration
          saturnism

          Paulo,

           

          Is putIntoCache a method in a session bean?  Could I trouble you to paste/attach that java file in its entirety?

           

          Thanks,

          • 2. Re: JPA cache store - JBoss AS 7 JTA configuration
            wdfink

            First of all I would ask "why you use a cache?"

            JPA include a first level cache which chache entities as long as you have an active context.

            This will be a good approach in most of the cases.

            Only exception is if you have master data wich are (mostly) read-only, in this case a local, or even a clustered distributed, cache might helpful for performance.

            • 3. Re: JPA cache store - JBoss AS 7 JTA configuration
              palov

              Yes, the methods are in a stateless session bean. Please take a look at the attached java file PayloadCacher.java.zip

              • 4. Re: JPA cache store - JBoss AS 7 JTA configuration
                palov

                The idea is to use a cache as low latency store for a large number of objects, which are to be stored in the database. We are not able to cache the DB writes into the fist level JPA cache, because every write is in a separate transaction.

                 

                What we need is some sort of write-behind caching (http://ehcache.org/documentation/recipes/writebehind), where we don't write data into DB directly during high loads. We would put data into the cache instead and write data to DB in a background thread or during low loads.

                • 5. Re: JPA cache store - JBoss AS 7 JTA configuration
                  saturnism

                  Palo,

                   

                  In SLSB, there are 2 ways to make this work... one is to use BMT on the SLSB, the other is to configure persistence.xml:

                   

                  <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="...">

                        ...

                        <properties>

                           <!-- Properties for Hibernate -->

                            ...

                   

                           <property name="hibernate.transaction.factory_class" value="org.hibernate.transaction.CMTTransactionFactory"/>

                           <property name="hibernate.transaction.manager_lookup_class" value="org.hibernate.transaction.JBossTransactionManagerLookup"/>

                           <property name="hibernate.connection.autocommit" value="false"/>

                           <property name="hibernate.current_session_context_class" value="jta"/>

                        </properties>

                     </persistence-unit>

                  </persistence>

                  • 6. Re: JPA cache store - JBoss AS 7 JTA configuration
                    palov

                    Thanks for the answer Ray. I assume the suggested configuration is correct. However I did not test this solution because we chose a different approach to handle the data. Maybe it becomes an option again, if we migrate to the next JBoss AS version.

                    • 7. Re: JPA cache store - JBoss AS 7 JTA configuration
                      toniortega

                      I have been working on a very similar environment and I'm almost sure that JpaCache store can't work with JtaTransactions. As stated in the EJB specification, EntityManager.getTransaction() method can only be used on application managed EntityMangers. So, in HIbernate implementation (AbstractEntityManagerImpl.java) we can see:

                       

                       

                        public EntityTransaction getTransaction() {

                        if ( transactionType == PersistenceUnitTransactionType.JTA ) {

                        throw new IllegalStateException( "A JTA EntityManager cannot use getTransaction()" );

                        }

                        return tx;

                        }

                       

                       

                      And JpaCahceStore is plenty of calls to getTransactionMethod(), so I think is not possible to use JpaCacheStore in an environment using JTA transactions (like EJB's with CMT).

                       

                      Can someone confirm this? Is there any option?

                      • 8. Re: JPA cache store - JBoss AS 7 JTA configuration
                        hamzabenmansour

                        Hi I have the same problem with JDG 6.3 and the hint given by Ray is not working for me. Do we have a working example with JPA Store and preload activated dealing with a JTA Datasource ?

                         

                        Best regards