4 Replies Latest reply on Aug 30, 2011 11:59 PM by mcaspers

    Envers, JBoss AS 7, and "Session is closed!" error

    mcasperson

      I have migrated a Seam application from AS 6 onto AS 7 CR1, and everything is working fine except for reading old versions of an audited entity. The code below used to work under AS 6, but now results in a org.hibernate.SessionException: Session is closed! error

       

      final AuditReader reader = AuditReaderFactory.get(this.getEntityManager());

      revisionInstance = reader.find(getEntityClass(), this.getId(), this.revision);

      revisionInstance.getSomeCollection();

       

      Does anyone have any idea why sessions might be treated differently in AS7?

       

      The full stack trace is:

       

      Caused by: org.hibernate.SessionException: Session is closed!
      at org.hibernate.internal.AbstractSessionImpl.errorIfClosed(AbstractSessionImpl.java:126)
      at org.hibernate.internal.SessionImpl.getPersistenceContext(SessionImpl.java:1790)
      at org.hibernate.envers.entities.mapper.relation.lazy.AbstractDelegateSessionImplementor.getPersistenceContext(AbstractDelegateSessionImplementor.java:223)
      at org.hibernate.proxy.AbstractLazyInitializer.setSession(AbstractLazyInitializer.java:120)
      at org.hibernate.proxy.AbstractLazyInitializer.<init>(AbstractLazyInitializer.java:74)
      at org.hibernate.proxy.pojo.BasicLazyInitializer.<init>(BasicLazyInitializer.java:60)
      at org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer.<init>(JavassistLazyInitializer.java:71)
      at org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer.getProxy(JavassistLazyInitializer.java:123)
      at org.hibernate.proxy.pojo.javassist.JavassistProxyFactory.getProxy(JavassistProxyFactory.java:69)
      at org.hibernate.tuple.entity.AbstractEntityTuplizer.createProxy(AbstractEntityTuplizer.java:644)
      at org.hibernate.persister.entity.AbstractEntityPersister.createProxy(AbstractEntityPersister.java:3768)
      at org.hibernate.envers.entities.mapper.relation.ToOneIdMapper.mapToEntityFromMap(ToOneIdMapper.java:95)
      at org.hibernate.envers.entities.mapper.MultiPropertyMapper.mapToEntityFromMap(MultiPropertyMapper.java:114)
      at org.hibernate.envers.entities.EntityInstantiator.createInstanceFromVersionsEntity(EntityInstantiator.java:98)
      at org.hibernate.envers.entities.mapper.relation.component.MiddleRelatedComponentMapper.mapToObjectFromFullMap(MiddleRelatedComponentMapper.java:42)
      at org.hibernate.envers.entities.mapper.relation.lazy.initializor.BasicCollectionInitializor.addToCollection(BasicCollectionInitializor.java:79)
      at org.hibernate.envers.entities.mapper.relation.lazy.initializor.BasicCollectionInitializor.addToCollection(BasicCollectionInitializor.java:40)
      at org.hibernate.envers.entities.mapper.relation.lazy.initializor.AbstractCollectionInitializor.initialize(AbstractCollectionInitializor.java:65)
      at org.hibernate.envers.entities.mapper.relation.lazy.proxy.CollectionProxy.checkInit(CollectionProxy.java:48)
      at org.hibernate.envers.entities.mapper.relation.lazy.proxy.CollectionProxy.iterator(CollectionProxy.java:68)
      at com.redhat.topicindex.entity.Topic.getTagsList(Topic.java:243)
      at com.redhat.topicindex.entity.Topic.getTagsList(Topic.java:225)
      at sun.reflect.GeneratedMethodAccessor317.invoke(Unknown Source)
      at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
      at java.lang.reflect.Method.invoke(Method.java:616)
      at javax.el.BeanELResolver.getValue(BeanELResolver.java:302)
      at javax.el.CompositeELResolver.getValue(CompositeELResolver.java:175)
      at com.sun.faces.el.FacesCompositeELResolver.getValue(FacesCompositeELResolver.java:72)
      at org.jboss.el.parser.AstPropertySuffix.getValue(AstPropertySuffix.java:53)
      at org.jboss.el.parser.AstValue.getValue(AstValue.java:67)
      at org.jboss.el.parser.AstChoice.getValue(AstChoice.java:29)
      at org.jboss.el.ValueExpressionImpl.getValue(ValueExpressionImpl.java:186)
      at com.sun.facelets.el.TagValueExpression.getValue(TagValueExpression.java:71)

        • 1. Re: Envers, JBoss AS 7, and "Session is closed!" error
          adamw

          Hmm if anywhere, I would expect this to happen during history writing, not reading, but audit gets written, right?
          Anyway, how do you obtain the EntityManager? Do you use the Hibernate bundled with AS7 and just add Envers, or do you include your own copy?

           

          Adam

          • 2. Re: Envers, JBoss AS 7, and "Session is closed!" error
            mcasperson

            The code below is where the old version of an entity is being loaded. The idea is that if revisionInstance == null (which will be the case if the revision variable has not been initialized) I use underlying EntityHome class as per usual. If revisionInstance != null I can read and display the properties of the Envers entity.

             

            As you can see from the commented code I have tried obtaining the EntityManager two different ways (although I suspect in the end both actually do the same thing). Neither made a difference.

             

            package com.redhat.topicindex.session;



            import javax.persistence.EntityManager;



            import org.hibernate.envers.AuditReader;

            import org.hibernate.envers.AuditReaderFactory;

            import org.jboss.seam.Component;

            import org.jboss.seam.framework.EntityHome;





            public abstract class VersionedEntityHome<E> extends EntityHome<E>

            {

                      protected Number revision;

                      protected E revisionInstance;


                      public void setRevision(final String revision)

                      {

                                try

                                {

                                          final Integer newRevision = revision==null?null:Integer.parseInt(revision);

                                          if (setDirty(this.revision, newRevision))

                                                    setInstance(null);

                                          this.revision = newRevision;


                                          if (this.revision == null)

                                          {

                                                    revisionInstance = null;

                                          }

                                          else

                                          {

                                                    //final EntityManager entityManager = (EntityManager) Component.getInstance("entityManager");

                                                    //final AuditReader reader = AuditReaderFactory.get(entityManager);

                                                    final AuditReader reader = AuditReaderFactory.get(this.getEntityManager());

                                                    revisionInstance = reader.find(getEntityClass(), this.getId(), this.revision);

                                          }


                                }

                                catch (Exception ex)

                                {

                                          System.out.println("TopicHome.setRevision() " + ex.toString());

                                          revisionInstance = null;

                                }

                      }



                      public String getRevision()

                      {

                                return revision==null?"":this.revision.toString();

                      }


                      public E getRevisionInstance()

                      {

                                return revisionInstance;

                      }

            }

             

             

            I can read all the other entity properties fine (i.e. those properties that map to fields in the table represented by the entity). The issue arrises when I try to read a collection held by a Envers entity. So

             

            <h:outputText value="#{empty topicHome.revision ? topicHome.instance.topicPrimaryKey : topicHome.revisionInstance.topicPrimaryKey}"/>

             

             

            works fine, while

             

            <h:outputText value="#{empty topicHome.revision ? topicHome.instance.someCollectionOfOtherEntities : topicHome.revisionInstance.someCollectionOfOtherEntities}"/>

             

             

            fails with the error from the original post.

             

            As to the question of whether I am using the version of Hibernate included with AS7 or including my own... In order to satisfy the class dependencies of Seam 2, I have had to include the following jars from AS6 into the WEB-INF/lib folder of my WAR:

             

            • hibernate-commons-annotations.jar
            • hibernate-core.jar
            • hibernate-entitymanager.jar
            • hibernate-jpa-2.2.0-api.jar
            • hibernate-validator.jar
            • hibernate-validator-legacy.jar

             

            However, due to the fact that Hibernate is an implicit module dependency in AS7 (https://docs.jboss.org/author/display/AS7/Implicit+module+dependencies+for+deployments under the Which are the implicit module dependencies? header), and they get processed first (https://docs.jboss.org/author/display/AS7/Class+Loading+in+AS7 under the Class Loading Precedence header), I susepct that I am actually using Hibernate 4.0.0 Beta1 (as supplied with AS7), and the JARs included in my WAR only get referenced for the few classes that are no longer provided with AS7, but which are still required by Seam 2. Thats an educated guess though, but one that is backed up by the fact that including hibernate-envers-4.0.0.Beta1.jar in my WAR allows me to read at least some properties from an Envers entity, while using the Envers JAR that worked with AS6 resulted in linking errors.

            • 3. Re: Envers, JBoss AS 7, and "Session is closed!" error
              adamw

              Ah! So you are probably using a mix of Hibernate 3 and 4 classes, which results in the problems.

               

              I am trying to run an application on AS7 which uses Envers, but so far without luck, see:

              http://community.jboss.org/message/618785#618785

               

              It seems like it will be fixed in 7.0.1, where you will have, above others, an option to bundle your own Hibernate.

               

              Adam

              • 4. Re: Envers, JBoss AS 7, and "Session is closed!" error
                mcaspers

                I have bundled Hibernate 3.6.7 using the instructions at https://docs.jboss.org/author/display/AS7/JPA+Reference+Guide with AS 7.01, and that has resolved the issue.