-->
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.  [ 2 posts ] 
Author Message
 Post subject: ScrollableResults closed by nested load
PostPosted: Tue Sep 17, 2013 5:27 am 
Newbie

Joined: Fri Feb 27, 2004 7:55 am
Posts: 17
Hi,

I have a HQL query that is executed by query.scroll() (see code below). The returned ScrollableResults can be iterated over without problems. Yet, when a session.load() operation is invoked in the loop then the next time scrollableResults.next() is called an exception is thrown that says that the result set is closed:

java.sql.SQLException: ResultSet not open. Operation 'next' not permitted. Verify that autocommit is off.

For the test a JTA user transaction and Derby was used. The problem occurs with Hibernate 4.2.5.Final.

Does anyone know a switch that prevents that the load operation causes the ScrollableResults to get closed? I already tried using a custom org.hibernate.context.internal.JTASessionContext where I overloaded the methods

Code:

   @Override
    protected ConnectionReleaseMode getConnectionReleaseMode() {
      return ConnectionReleaseMode.AFTER_TRANSACTION;
    }

    @Override
    protected boolean isAutoCloseEnabled() {
      return false;
    }


(BTW: When I use plain SQL to do the same, then no exception occurs).

TIA

--Stefan

Code:
    // Test-Code using HQL that throws an exception:
    Session session = sessionFactory.getCurrentSession();
    String attrKey = "attrAttr";
    String entityName = "e_d_test";
    session.save(entityName, newEntity(attrKey));
    session.save(entityName, newEntity(attrKey));
    session.flush();
    Query query = session.createQuery("from " + entityName);
    ScrollableResults scrollableResults = query.scroll();
    while (scrollableResults.next()) {
      Object o = scrollableResults.get();
      Map entityObject = (Map) ((Object[]) o)[0];
      Serializable instanceId = session.getIdentifier(entityObject);
      System.out.println("instanceId: " + instanceId);
      Object loaded = session.load(entityName, instanceId);
      System.out.println("loaded: " + loaded);
    }


Code:
    // Test-Code using plain SQL that does not throw an exception:
    DataSource ds = (DataSource)new InitialContext().lookup("java:comp/env/jdbc/myDbHost2.w1");
    Connection con = ds.getConnection("f5", null);
    con.createStatement().execute("insert into F5_E_D_TEST (ID, VERSION, A_ATTR) values (1, 1, 'x')");
    con.createStatement().execute("insert into F5_E_D_TEST (ID, VERSION, A_ATTR) values (2, 2, 'y')");
    ResultSet rs = con.createStatement().executeQuery("select * from F5_E_D_TEST");
    while (rs.next()) {
      long id = rs.getLong("ID");
      System.out.println("id: " + id);
      ResultSet rs2 = con.createStatement().executeQuery("select * from F5_E_D_TEST where id = " + id);
      while (rs2.next()) {
        String attr = rs2.getString("A_ATTR");
        System.out.println("attr: " + attr);
      }
    }


Top
 Profile  
 
 Post subject: Re: ScrollableResults closed by nested load
PostPosted: Tue Sep 17, 2013 6:52 am 
Newbie

Joined: Fri Feb 27, 2004 7:55 am
Posts: 17
I debugged for a while and collected the following information: The result set is closed after the load operation has completed by the SessionImpl.afterOperation() method, because the transaction coordinater returns false when asked isTransactionInProgress():

Code:
   public void afterOperation(boolean success) {
      if ( ! transactionCoordinator.isTransactionInProgress() ) {
         transactionCoordinator.afterNonTransactionalQuery( success );
      }
   }


In that case TransactionCoordinater cleans up:

Code:
   public void afterNonTransactionalQuery(boolean success) {
      // check to see if the connection is in auto-commit mode (no connection means aggressive connection
      // release outside a JTA transaction context, so MUST be autocommit mode)
      boolean isAutocommit = getJdbcCoordinator().getLogicalConnection().isAutoCommit();
      getJdbcCoordinator().afterTransaction();

      if ( isAutocommit ) {
         for ( TransactionObserver observer : observers ) {
            observer.afterCompletion( success, this.getTransaction() );
         }
      }
   }


where JdbcCoordinater.afterTransaction() closes all Statements and ResultSets that were opened by during the current session. Apparently the problem is, that transactionCoordinator.isTransactionInProgress() returns false. The following code is executed:

Code:
   public boolean isTransactionInProgress() {
      return getTransaction().isActive() && getTransaction().getJoinStatus() == JoinStatus.JOINED;
   }


Here getTransaction().isActive() returns false. The instance org.hibernate.engine.transaction.internal.jta.JtaTransaction checks:

Code:
   public boolean isActive() throws HibernateException {
      if ( getLocalStatus() != LocalStatus.ACTIVE ) {
         return false;
      }

      final int status;
      try {
         status = userTransaction.getStatus();
      }
      catch ( SystemException se ) {
         throw new TransactionException( "Could not determine transaction status: ", se );
      }
      return JtaStatusHelper.isActive( status );
   }


Unfortunately, getLocalStatus() returns "NOT_ACTIVE" which causes the check to return false.

I wonder if the method JtaTransaction.isActive() has a bug because it checks its local status member. The local status member is set to "ACTIVE" only when the begin() method of the transaction instance is called explicitly. However, I thought that if JTA user transactions are used, then someone has not to care about Hibernate transactions. Begin/Commit/Rollback is signalled on the user transaction instance.

As a workaround I added the following lines of code to the HQL test:

Code:
    Session session = sessionFactory.getCurrentSession();
    session.beginTransaction();


This seems to work.

Could some initiate comment on this please?

TIA

--Stefan


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 2 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:
cron
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.