5 Replies Latest reply on Oct 12, 2004 10:02 AM by adrian.brock

    Connections - close them yourself - but - I am trying to

    chrissearle

      OK - I know the faq - if a connection is open then you should close it.

      Here's the setup

      Hibernate session factory set up as an MBean available over JNDI.

      Stateful session bean - state includes amongst other things a hibernate session - retrieved from the factory which was fetched with a JNDI lookup.

      The bean has a

      private Session getSession() {
      if (session == null) {
      // get the factory and then from there get the session - set the session instance variable
      }

      return session;
      }

      In passivate/remove the session is closed - then set to null.

      In activate/create the session is not opened - getSession() handles this when needed - no point in connecting if we're not going to use it

      Everything works except I get the "Closing a connection for you. Close them yourself" message.

      So - in the log I get (when I call bean.remove()):

      Exception - Closing a connection. Close them yourself
      ejbRemove called
      closing session
      session closed

      So - I am trying to close the thing - during ejbRemove here - what is triggering the "Close them yourself" error (in other words - what has spotted an open connection after remove() but before ejbRemove())?

      This is driving me nuts at the moment.

        • 1. Re: Connections - close them yourself - but - I am trying to
          chrissearle

          Followup from some testing

          If I try

          bean = home.create();
          
          bean.method1();
          
          bean.method2();
          
          bean.remove();
          


          then - after method1 completes (on method exit) Jboss shouts:

          2004-10-05 23:36:09,053 INFO [org.jboss.resource.connectionmanager.CachedConnectionManager] Closing a connection for you. Please close them yourself: org.jboss.resource.adapter.jdbc.WrappedConnection@1870cfc
          java.lang.Exception: STACKTRACE
          ...
          


          bean.method2() finds an existing hibernate session (in the stateful beans state) - but - when it tries to access this session it gets told that the underlying database connection is closed.

          Can a connection not be held in a stateful beans state?

          The config for the bean looks like:

           <session >
           <description>>Config lookup bean (key/val)</description>
           <ejb-name>AdminSB</ejb-name>
           <home>org.longship.joti.ejb.interfaces.AdminSBHome</home>
           <remote>org.longship.joti.ejb.interfaces.AdminSB</remote>
           <ejb-class>org.longship.joti.ejb.session.AdminSBSession</ejb-class>
           <session-type>Stateful</session-type>
           <transaction-type>Container</transaction-type>
           </session>
          




          • 2. Re: Connections - close them yourself - but - I am trying to
            ronaldoc

            Chris,

            From the looks of your code, it looks like you're coding to an anti-pattern. See http://blog.hibernate.org/cgi-bin/blosxom.cgi/2004/01/27#perf-problems

            Have you tried this: only call flush or commit at the last method ? This is probably what Gavin is describing in his blog item e.g. session-per-application-transaction-with-flush-delayed-to-the-last-request

            Regards,

            Ronaldo

            • 3. Re: Connections - close them yourself - but - I am trying to
              chrissearle

              I'm trying for what I guess I'd call

              session-per-request-but-keep-the-session-in-the-ejb-layer.

              So - a request comes in (servlet). That creates a service object (business layer stub) which will call the business logic in the session beans.

              To avoid session-per-operation (which was the code I inherited) I thought - OK - let's move the session into the state of the bean.

              So logic should be:

              bean = home.create();
              
              bean.method1(); // Calls getSession - Session created
              
              bean.method2(); // Calls getSession - returns stored session
              
              bean.remove(); // Session removed.
              


              Note - you need to nullify the session at passivate (or at least I think you do) - so the getSession method was created - to create a session if one didn't exist from before or if passivate had been called. This would look like

              bean = home.create();
              
              bean.method1(); // Calls getSession - Session created
              
              Bean passivated - session closed
              
              bean.method2(); // Calls getSession - Session created
              
              bean.remove(); // Session removed.
              


              The problem is that when method1 exits - then I get the
              2004-10-05 23:36:09,053 INFO [org.jboss.resource.Connectionmanager.CachedConnectionManager] Closing a connection for you. Please close them yourself: org.jboss.resource.adapter.jdbc.WrappedConnection@1870cfc
              java.lang.Exception: STACKTRACE


              error - even though the session is stored in an active stateful session beans session.

              NB - this is a gradual process - moving now from session per operation to session per bean per request - will move to session per request if I can figure out how to share the session between bean instances without returning it over RMI from the EJB container.

              • 4. Re: Connections - close them yourself - but - I am trying to
                chrissearle

                OK - I've removed the exception.

                The bean now implements javax.ejb.SessionSynchronization - and in the beforeCompletion method it calls session.disconnect(). In the getSession method it calls session.reconnect().

                So - the session stays but the connection doesn't.

                (Have the feeling this is getting far far off the JCA topic here :-))

                So - I have one-session-per-ejb-per-request-but-that-connects-disconnects-with-each-method-call

                Now all I need to figure out how to share a given session between session beans that are used in the same request (servlet/application) and maybe to keep the connection open (not sure if it's a good idea to do this or not -or even if it's possible).

                • 5. Re: Connections - close them yourself - but - I am trying to

                  beforeCompletion is not invoked if the transaction rollsback