12 Replies Latest reply on Nov 18, 2011 3:56 PM by galder.zamarreno

    Intergation issue with Infinispan 5.1 and hibernate

    slorg1

      Hi,

       

      I am running into a bit of a pickle integrating the new(er) Beta 4 with hibernate when using the cache as transactional AND autoCommit FALSE.

       

       

      Caused by: org.hibernate.cache.CacheException: java.lang.IllegalStateException: This is a tx cache!

                at org.hibernate.cache.infinispan.util.CacheAdapterImpl.put(CacheAdapterImpl.java:98)

                at org.hibernate.cache.infinispan.util.CacheHelper.initInternalEvict(CacheHelper.java:53)

                at org.hibernate.cache.infinispan.impl.BaseRegion.establishInternalNodes(BaseRegion.java:83)

                at org.hibernate.cache.infinispan.impl.BaseRegion.start(BaseRegion.java:70)

                at org.hibernate.cache.infinispan.InfinispanRegionFactory.buildEntityRegion(InfinispanRegionFactory.java:176)

                at org.hibernate.impl.SessionFactoryImpl.<init>(SessionFactoryImpl.java:291)

                at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1385)

                at org.hibernate.cfg.AnnotationConfiguration.buildSessionFactory(AnnotationConfiguration.java:954)

                at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:891)

                ... 33 more

      Caused by: java.lang.IllegalStateException: This is a tx cache!

                at org.infinispan.context.TransactionalInvocationContextContainer.createInvocationContext(TransactionalInvocationContextContainer.java:71)

                at org.infinispan.CacheImpl.getInvocationContext(CacheImpl.java:432)

                at org.infinispan.CacheImpl.getInvocationContextWithImplicitTransaction(CacheImpl.java:420)

                at org.infinispan.CacheImpl.put(CacheImpl.java:629)

                at org.infinispan.DecoratedCache.put(DecoratedCache.java:297)

                at org.hibernate.cache.infinispan.util.CacheAdapterImpl.put(CacheAdapterImpl.java:96)

                ... 41 more

       

       

      The issue here is that the cache is set as transactional and when using the EntityManagerFactory from hibernate,

       

      at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:900)

       

      even though I started a transaction, the org.hibernate.cache.infinispan.impl.BaseRegion suspends the transaction when sending an evict all in the cache (at start up).

       

      That causes the cache to crash (stack trace above), complaining that it is transactional and no transaction exists (logical since it was suspended).

       

      The questions would then be:

      Is there a new piece of code for integrating with hibernate (I checked hibernate 4.0.0.CR5 and it is the same code)?

       

      Why does the transaction need to be suspended if the cache is transactional?

       

       

      Thank you in advance,

        • 1. Re: Intergation issue with Infinispan 5.1 and hibernate
          galder.zamarreno

          Which environment are you running this in? What is the transaction manager are you using?

          • 2. Re: Intergation issue with Infinispan 5.1 and hibernate
            slorg1

            Hi Galder,

             

            I am using Atomikos 3.7.0 as my transaction manager.

             

            Obviously I am using infinispan 5.1.BETA 4 and hibernate 3.5.5.

             

            The OS is linux (debian for my dev machine and CentOS for the test machine) and we both run a JRE 6 (1.6.0_26-b03).

             

            I am not sure how the transaction manager would change the behaviour of the infinispan in this precise case given that the transaction is effectively suspended as expected from the code.

             

            Thank you,

            • 3. Re: Intergation issue with Infinispan 5.1 and hibernate
              galder.zamarreno

              @slorg, it does matter because even if we suspend it, the cache code will find the transaction is null and will start a new one, see https://github.com/infinispan/infinispan/blob/5.1.0.BETA4/core/src/main/java/org/infinispan/CacheImpl.java#L408

               

              What is more likely happening here is that your transaction manager is not correctly set up. Debug the code and find out which transaction manager would be hit in that code...etc.

              • 4. Re: Intergation issue with Infinispan 5.1 and hibernate
                galder.zamarreno

                Well, assuming that autoCommit is true of course, but in your case is set to false, right? The workaround is there at least. We will check what the right settings should be for autoCommit in this use case.

                • 5. Re: Intergation issue with Infinispan 5.1 and hibernate
                  slorg1

                  Hi Galder,

                   

                  I did run the debug and went through the code prior to sending this message and as far as I can tell Atomikos is doing the right thing.

                   

                  Right, in my case all the work is wrapped in a transaction and I turned autoCommit off (false) as I have my own transactions handled at a different level.

                   

                  If I have autoCommit set to true infinispan happily begins a new transaction and it moves on from there but having autoCommit to true has undesirable side effects for me. Allow me to compile them for you.

                   

                  I also have issues understanding why the transactional cache would supsend my transaction to begin new ones that it auto commits.

                   

                   

                  Thank you,

                  • 6. Re: Intergation issue with Infinispan 5.1 and hibernate
                    slorg1

                    Hi Galder,

                     

                    So I went back to the autoCommit(true) and here is the behaviour I find:

                     

                    -> start a transaction in my application (I will call it, AT)

                    -> I invoke a find from hibernate

                    -> Hibernate loads the data

                    -> in the glue code between hibernate and infinispan, a putFromLoad is called

                    -> the putFromLoad in turn calls the putFromExternalRead on the Infinispan cache

                    -> at this point Infinispan suspends my transaction (AT)

                    -> auto create a new one (since I have autoCommit true and no more running transaction for this thread)

                    -> does the put, does the replication

                    -> commits the auto created transaction

                    -> resumes my transaction(AT)

                     

                    This seems very odd to me in a transactional context.

                     

                    Also the putForExternalRead has a javadoc saying:

                    {quote} Ongoing transactions are suspended before this call, so

                    so failures here will not affect any ongoing transactions. {quote}

                     

                    Does that not kind of defeat the purpose of transactions?

                     

                    In addition, all these transactions related commands are all replicated being extremely expensive (my cache is replicated and transactional).

                    This is why I had turned off the auto commit originally as I did not feel like it made the cache respect the transaction isolation and behaviour, hoping that it would stop spawning new transactions and auto committing them.

                     

                    Please let me know if I missed something as what I am describing does not seem very transactional.

                     

                    Thank you,

                    • 7. Re: Intergation issue with Infinispan 5.1 and hibernate
                      galder.zamarreno

                      You have a point about autoCommit needing to be false. I'm yet to do further testing to verify the behaivour of autoCommit = false with Hibernate 2LC. So, I think autoCommit=true, even though it's kinda wasteful, but it's a valid workaround here.

                       

                      Wrt putForExternalRead, a further discussion is needed to figure out what to do with autoCommit. See http://lists.jboss.org/pipermail/infinispan-dev/2011-November/009470.html for a follow up development discussion. Feel free to join

                      • 8. Re: Intergation issue with Infinispan 5.1 and hibernate
                        slorg1

                        Hi Galder,

                        Galder Zamarreño wrote:

                         

                        You have a point about autoCommit needing to be false. I'm yet to do further testing to verify the behaivour of autoCommit = false with Hibernate 2LC. So, I think autoCommit=true, even though it's kinda wasteful, but it's a valid workaround here.

                        Well, it is "valid" in the sense that it gets the replication going but it is not so "valid' when it comes to transaction isolations and certainly would not guarranty the REPEATABLE_READ setting across nodes.

                         

                        I joined your mail list, I am looking forward to assisting you in that matter.

                         

                        I also found something else which does not seem to behave but it is on a different topic so I am going to start a new thread.

                        • 9. Re: Intergation issue with Infinispan 5.1 and hibernate
                          galder.zamarreno

                          @slorg1, the reason because those transactions are suspended, whether when setting those evict markers or in putForExternalRead(PFER) is because they do not affect your actual transaction. These are particular operations designed to work in that way. So, I stand by what I said, if anything, autoCommit=true is wasteful, but won't affect your app.

                           

                          Back to your autoCommit=false testing, I've been doing some testing myself and have not been able to replicate the same failure you have with this setting. So, please provide a test case that I can run locally that can help me figure out what's wrong in your particular case.

                          • 10. Re: Intergation issue with Infinispan 5.1 and hibernate
                            slorg1

                            Hi Galder,

                             

                            About #1: unless I am missing something, it kind of does affect my application in the sense that the "version" of the object being replicated belongs to a different transaction which has not been committed. How does that not causes issues when being replicated to different nodes, which in turn could have modified it? In that case the "new" transaction should fail and the error run back up the trace for a potential rollback, which it cannot here.

                            I do question the REPEATABLE_READ with that "auto" create transactions, given that they effectively commit in the cache objects that belong to uncommitted transactions across the board (locally and remotely). I mean it may be remote cases but I think they can happen.

                             

                            About #2:

                             

                            I do not have a test case per se as it is part of the whole application at this point. However, for having fidgeted with it for a while, do make sure that the autoCommit is set to FALSE, the Configuration class provided with the BETA 4 does not let it happen.

                            To make sure, I added debug code in "getInvocationContextWithImplicitTransaction" to make sure the auto commit is set to false, otherwise it silently "works" (#1 I make sure the this.config.isTransactionalCache() yields true and then I see my "ongoing" transaction be null and the auto commit being set to false. )

                             

                            If autoCommit is set to FALSE AND the cache is TRANSACTIONAL, the crash is systematic for me.

                             

                            Thank you,

                            • 11. Re: Intergation issue with Infinispan 5.1 and hibernate
                              galder.zamarreno

                              Re 1: First of all, a PFER is a local operation and never replicates. Secondly, it cannot be a different version to another transaction because this comes from something read in the database, which is the ultimate source of information. So, if two different nodes are going to update an entity, they will read the same entity from the database and each will load it locally. That's what PFER does . When it comes to updating, normal rules apply. For the final time, that auto created transaction (via PFER) does not affect entity updates.

                               

                              Re 2: Yeah, the autoCommit configuration wasn't working correctly. I've finally fully fixed it now and I can replicate your exception now.

                              • 12. Re: Intergation issue with Infinispan 5.1 and hibernate
                                galder.zamarreno

                                Re 1: Actually, it's replicated (asynchronous) rather than local, but the result is the same.