-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 3 posts ] 
Author Message
 Post subject: ScrollableResults: proxy handle is no longer valid
PostPosted: Thu Mar 22, 2012 1:21 pm 
Newbie

Joined: Mon Nov 19, 2007 8:40 am
Posts: 5
We are using Hibernate 4.1.1.Final with Spring's JtaTransactionManager, LocalSessionFactoryBean and SpringSessionContext. We have set:

Code:
hibernate.transaction.jta.platform=org.hibernate.service.jta.platform.internal.JBossAppServerJtaPlatform
hibernate.transaction.factory_class=org.hibernate.transaction.JTATransactionFactory


We need to use the criteria and query scroll() functionality in order to process large result sets in a memory efficient manner. The code can be boiled down to the following snippet...

Code:
ScrollableResults results = getCurrentSession().createQuery("some hql....").scroll();
while (results.next()) {
  process(results.get(0));
}
results.close();


However since upgrading Hibernate (from 3.6.7) (and replacing Spring's HibernateTemplate with the recommended sessionFactory.getCurrentSession() calls) we have had a problem with those cases that access the Hibernate session during the iteration (e.g. process(...) does getCurrentSession().get(entityName,id)).

On the subsequent call to results.next() we get the following exception thrown...

Code:
org.hibernate.HibernateException: proxy handle is no longer valid
   at org.hibernate.engine.jdbc.internal.proxy.AbstractProxyHandler.errorIfInvalid(AbstractProxyHandler.java:63)
   at org.hibernate.engine.jdbc.internal.proxy.AbstractResultSetProxyHandler.continueInvocation(AbstractResultSetProxyHandler.java:84)
   at org.hibernate.engine.jdbc.internal.proxy.AbstractProxyHandler.invoke(AbstractProxyHandler.java:81)
   at $Proxy161.next(Unknown Source)
   at org.hibernate.internal.ScrollableResultsImpl.next(ScrollableResultsImpl.java:116)


What seems to happen is that SessionImpl.afterOperation(boolean) (called when the get of the entity or whatever completes) thinks that there is no active transaction (though there *is* an active JTA transaction) and so it closes the scrollable resultset.

In Hibernate 4.1.1, org.hibernate.engine.transaction.internal.jta.JtaTransaction.isActive() is used to determine whether there is a transaction active. However this immediately returns false if there is no local (?) tx. It is as if we should be calling session.beginTransaction() to set an active local tx even though our transactions are JTA and managed declaratively.

Not sure whether this is an issue with Hibernate or with Spring. It just seems that this ought to work.

Any ideas? (Let me know if you need more info.)


Top
 Profile  
 
 Post subject: Re: ScrollableResults: proxy handle is no longer valid
PostPosted: Thu Mar 22, 2012 3:39 pm 
Expert
Expert

Joined: Tue Jun 16, 2009 3:36 am
Posts: 990
Hm, you get the same exception as another 2 users reported some days ago in this thread:
https://forum.hibernate.org/viewtopic.php?f=1&t=1014673


Top
 Profile  
 
 Post subject: Re: ScrollableResults: proxy handle is no longer valid
PostPosted: Fri Mar 23, 2012 8:48 am 
Newbie

Joined: Mon Nov 19, 2007 8:40 am
Posts: 5
After a bit of digging it looks like the problem is related to using org.hibernate.transaction.JTATransactionFactory. It works with org.hibernate.transaction.CMTTransactionFactory.

Maybe use of the former with Spring-managed transactions (in a JTA environment) is not a valid combination for certain use cases.

If so then perhaps, to assist others, the Using JTA section in the manual should warn against this: I'm not sure that the naming CMT/JTATransactionFactory makes it obvious.

Here is some unit test code just in case this is a regression from Hibernate 3.x. The test testQueryScrolling (lifted from AggressiveReleaseTest) passes but testQueryScrolling_intermediateGet fails with the exception in the initial post...

Many thanks.

Code:
package org.hibernate.test.connections;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

import org.hibernate.ConnectionReleaseMode;
import org.hibernate.ScrollableResults;
import org.hibernate.Session;
import org.hibernate.cfg.Configuration;
import org.hibernate.cfg.Environment;
import org.hibernate.engine.transaction.internal.jta.JtaTransactionFactory;
import org.hibernate.testing.jta.TestingJtaBootstrap;
import org.junit.Test;

/**
* Implementation of JTATxScrollingTest.
*
* @author Jeremy Stone
*/
public class JTATxScrollingTest extends ConnectionManagementTestCase {
   @Override
   public void configure(Configuration cfg) {
      super.configure(cfg);
      TestingJtaBootstrap.prepare(cfg.getProperties());
      cfg.setProperty(Environment.TRANSACTION_STRATEGY,
            JtaTransactionFactory.class.getName());
      cfg.setProperty(Environment.RELEASE_CONNECTIONS,
            ConnectionReleaseMode.AFTER_STATEMENT.toString());
      cfg.setProperty(Environment.GENERATE_STATISTICS, "true");
      cfg.setProperty(Environment.STATEMENT_BATCH_SIZE, "0");
   }

   @Override
   protected Session getSessionUnderTest() throws Throwable {
      return openSession();
   }

   @Override
   protected void reconnect(Session session) {
   }

   @Override
   protected void prepare() throws Throwable {
      TestingJtaBootstrap.INSTANCE.getTransactionManager().begin();
   }

   @Override
   protected void done() throws Throwable {
      TestingJtaBootstrap.INSTANCE.getTransactionManager().commit();
   }

   @Test
   public void testQueryScrolling() throws Throwable {
      prepare();
      Session s = getSessionUnderTest();
      Silly silly = new Silly("silly");
      s.save(silly);
      s.flush();

      ScrollableResults sr = s.createQuery("from Silly").scroll();
      assertTrue(sr.next());
      Silly silly2 = (Silly) sr.get(0);
      assertEquals(silly, silly2);
      sr.close();

      sr = s.createQuery("from Silly").scroll();
      ScrollableResults sr2 = s
            .createQuery("from Silly where name = 'silly'").scroll();

      assertTrue(sr.next());
      assertEquals(silly, sr.get(0));
      assertTrue(sr2.next());
      assertEquals(silly, sr2.get(0));

      sr.close();
      sr2.close();

      s.delete(silly);
      s.flush();

      release(s);
      done();
   }

   @Test
   public void testQueryScrolling_intermediateGet() throws Throwable {
      prepare();
      Session s = getSessionUnderTest();

      Silly silly1 = new Silly("silly1");
      s.save(silly1);
      Silly silly2 = new Silly("silly2");
      s.save(silly2);

      s.flush();

      ScrollableResults sr = s.createQuery("from Silly order by name")
            .scroll();

      assertTrue(sr.next());
      Silly _silly1 = (Silly) sr.get(0);
      assertEquals(_silly1, silly1);

      s.get(Silly.class, silly2.getId());

      assertTrue(sr.next());
      Silly _silly2 = (Silly) sr.get(0);
      assertEquals(_silly2, silly2);

      assertFalse(sr.next());

      sr.close();

      s.delete(silly1);
      s.delete(silly2);
      s.flush();

      release(s);
      done();
   }
}


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 3 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.