2 Replies Latest reply on Nov 23, 2011 9:43 AM by thomas10

    could not initialize lazy properties when using build time instrumentation

    thomas10

      We are trying to enable build time instrumentation for our product. The main reason is to enable lazy loading of to-one relations. Everything seems to work fine except for our import process. The import reads from one database (raw sql, no hibernate involved) and writes to our hibernate mapped database. The import runs periodically from a @Timeout method in a @Singleton. There is more than one importer so the singleton just delegates to another ejb (also a @Singleton).

      As I understand session scopes everything should just run under one session. Bound to one large transaction. Of course we do some kind of batching but that was completely removed for testing purposes. So there should be no problems whatsoever. I am aware that this exception is almost always raised with more than one session involved but this is not the case here as far as I can tell. Everything runs from within one EJB method.

       

      Unfortunately I do get an exception (full stack trace attached):

       

      16:10:16,553 ERROR [org.jboss.ejb3.tx2.impl.CMTTxInterceptor] javax.ejb.EJBTransactionRolledbackException: could not initialize lazy properties: [com.mycompany.database.Order#1065]

      16:10:16,561 ERROR [com.mycompany.importservice.ImportService] Unhandled exception.: javax.ejb.EJBTransactionRolledbackException: could not initialize lazy properties: [com.mycompany.database.Order#1065]

          at org.jboss.ejb3.tx2.impl.CMTTxInterceptor.handleInCallerTx(CMTTxInterceptor.java:148) [:0.0.1]

          at org.jboss.ejb3.tx2.impl.CMTTxInterceptor.invokeInCallerTx(CMTTxInterceptor.java:227) [:0.0.1]

          at org.jboss.ejb3.tx2.impl.CMTTxInterceptor.required(CMTTxInterceptor.java:353) [:0.0.1]

          at org.jboss.ejb3.tx2.impl.CMTTxInterceptor.invoke(CMTTxInterceptor.java:209) [:0.0.1]

          at org.jboss.ejb3.tx2.aop.CMTTxInterceptorWrapper.invoke(CMTTxInterceptorWrapper.java:52) [:0.0.1]

          at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102) [jboss-aop.jar:2.2.1.Alpha3]

          at org.jboss.aspects.tx.TxPropagationInterceptor.invoke(TxPropagationInterceptor.java:76) [:1.0.0.GA]

          at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102) [jboss-aop.jar:2.2.1.Alpha3]

          at org.jboss.ejb3.tx.NullInterceptor.invoke(NullInterceptor.java:42) [:1.0.3]

          ...

         

      Caused by: java.sql.SQLException: The result set is closed.

          at org.jboss.resource.adapter.jdbc.WrappedResultSet.checkState(WrappedResultSet.java:1959) [:6.0.0.20101110-CR1]

          at org.jboss.resource.adapter.jdbc.WrappedResultSet.getInt(WrappedResultSet.java:695) [:6.0.0.20101110-CR1]

          at org.hibernate.type.descriptor.sql.IntegerTypeDescriptor$2.doExtract(IntegerTypeDescriptor.java:61) [:3.6.0.Final]

          at org.hibernate.type.descriptor.sql.BasicExtractor.extract(BasicExtractor.java:64) [:3.6.0.Final]

          at org.hibernate.type.AbstractStandardBasicType.nullSafeGet(AbstractStandardBasicType.java:253) [:3.6.0.Final]

          at org.hibernate.type.AbstractStandardBasicType.nullSafeGet(AbstractStandardBasicType.java:249) [:3.6.0.Final]

          at org.hibernate.type.AbstractStandardBasicType.nullSafeGet(AbstractStandardBasicType.java:229) [:3.6.0.Final]

          at org.hibernate.type.ManyToOneType.hydrate(ManyToOneType.java:146) [:3.6.0.Final]

          at org.hibernate.type.EntityType.nullSafeGet(EntityType.java:234) [:3.6.0.Final]

          at org.hibernate.persister.entity.AbstractEntityPersister.initializeLazyPropertiesFromDatastore(AbstractEntityPersister.java:853) [:3.6.0.Final]

          ... 138 more

       

       

      I have tried to remove all session.close() and session.flush() calls. There are no calls to session.evict().

       

      So my question is: what have I missed? Is it correct that I have no problems with lazy properties as long as my code runs inside one transaction/session? Or are there some "special circumstances" that can change the game?

       

      Other things that might be of interest:

       

      The application creates a hibernate configuration with something like:

       

      Configuration configuration = new Configuration();

      configuration.addAnnotatedClass(...);

      configuration.buildMappings();

       

      A session is retrieved via JNDI lookup and a call to sessionFactory.getCurrentSession(). No EntityManager here.

       

      Tested with JBoss 6.1.0 and JBoss 6.0 CR1, MS SQL Server 2008R2, Windows 7 x64.

       

      To be clear: everything works when buildtime instrumentation is turned off.

       

       

      Thanks for your help.

        • 1. Re: could not initialize lazy properties when using build time instrumentation
          thomas10

          Ok, I have more information.

           

          The import is performed in batches and each batch is triggered from a @Timeout. So each batch runs in its own session context.

           

          If I set the batch size to 1 my import starts working again. Of course this is no solution (think performance).

          Our domain model consists of Projects that can belong to BusinessTransactions. The relation is ManyToOne

          (many Projects can share one BusinessTransaction).

          When a Project is imported an existing BusinessTransaction is searched and assigned if it exists. If it does not exist

          a new BusinessTransaction is created). The BusinessTransaction is loaded using

           

          BusinessTransaction businessTransaction = (BusinessTransaction) psession

              .createCriteria(BusinessTransaction.class)

              .add(Restrictions.eq(BusinessTransaction.PROP_IMPORT_KEY, orderImportKey))

              .setCacheable(true)

              .setMaxResults(1).uniqueResult();

           

          if (businessTransaction == null) {

              businessTransaction = new BusinessTransaction();

              businessTransaction.setImportKey(orderImportKey);

              ...

              psession.saveOrUpdate(businessTransaction);

          }

           

           

          The first imported project loads an existing BusinessTransaction. No exception.

          The second imported project loads the same BusinessTransaction. Exception is raised.

           

          EDIT: calling session.flush() after the first project is imported does not change anything.

           

          Any suggestions what I am doing wrong?

          • 2. Re: could not initialize lazy properties when using build time instrumentation
            thomas10

            Ok, I've had finally time to resolve this bug. We've had mixed @Proxy attributes on our entities. Some classes had @org.hibernate.annotations.Proxy(lazy = true) and some @org.hibernate.annotations.Proxy(lazy = false).

             

            Changing all annotations to lazy=true resolves the bug (lazy=false works too). I have no idea why this resulted in an exception. http://docs.jboss.org/hibernate/annotations/3.5/reference/en/html/entity.html#entity-hibspec-entity does not state any restrictions.

             

            Anybody knows why I am not allowed to mix these annotations?