11 Replies Latest reply on Jul 24, 2006 1:09 PM by mamgoncalves

    Need clarification: Trying to return an unknown connection2

      I know this one has been around the block before, but I ask for your patience and just wanted some clarification.

      I have a situation where an MDB (which is using bean-managed transactions) is calling to a stateless session bean. In the scenario, the MDB has no current transaction, but calls over to a SLSB method which has a "RequiresNew" transaction attribute.

      The SLSB method itself uses Hibernate and uses the HibernateContext.getSession(String) method to get the Hibernate session. The SLSB method does not explicitley close the Hibernate session.

      When the SLSB method returns, I see the "Trying to return an unknown connection2" INFO message in the server log file.

      After reading through several board postings, this posting seems most relevent - http://www.jboss.com/index.html?module=bb&op=viewtopic&t=59294

      So given the instructions there: "The workaround is remove the CachedConnectionInterceptor from the container configuration" , I go through the standardjboss.xml and remove all references to the CachedConnectionInterceptor interceptor.

      This seems to have cleared up the "Trying to return an unknown connection2" message, however I do have some questions:

      Has making this change had any detremental affect? I allow Hibernate to manage all of my connections, but have I just introduced any possibility of a connection leak?

      Should I remove CachedConnectionInterceptor for all container-configurations or just for "Standard Stateless SessionBean"? Is there any drawback to this workaround?

      Thanks for your attention.

        • 1. Re: Need clarification: Trying to return an unknown connecti

          http://wiki.jboss.org/wiki/Wiki.jsp?page=JBossHelp
          Ignored already answered question which you found and isn't even relevant with the
          latest hibernate.

          • 2. Re: Need clarification: Trying to return an unknown connecti

            Mod: Troll

            Anyone out there have a helpful answer?

            • 3. Re: Need clarification: Trying to return an unknown connecti

              I'm really at a loss trying to see where this:

              http://www.jboss.com/index.html?module=bb&op=viewtopic&t=59294

              or this:

              http://jira.jboss.com/jira/browse/JBAS-1428?rc=1

              address the implications of the workaround.

              I see someone else ask the same question here:

              http://www.jboss.com/index.html?module=bb&op=viewtopic&t=60181

              and it goes unanswered. You state:

              "If you don't follow the spec semantics, the CCM won't understand what you are doing."


              Does this imply that Hibernate2 does not "follow the spec semantics"?

              In the JIRA report you state:

              "This should not be a bug report since it only applies to frameworks not following EJB rules."


              Does this than imply that Hibernate2 is a framework that "does not follow EJB rules"?

              You also state that this:

              "isn't even relevant with the latest hibernate."


              So is this a known fixed bug in Hibernate3?

              I've seen you flame people many times before on this question, which is why I asked for patience and clarification.


              Over here:

              http://www.jboss.com/index.html?module=bb&op=viewtopic&t=63795

              you imply that this item is in the FAQ. Where is this FAQ entry? I don't see it in here:

              http://www.jboss.org/wiki/Wiki.jsp?page=FAQJBossJCA

              And yes, I did do a forum and Wiki search and read every search result.


              • 4. Re: Need clarification: Trying to return an unknown connecti

                 

                "twalsh2" wrote:
                Mod: Troll

                Anyone out there have a helpful answer?


                A Troll is somebody looking for an argument.

                I'm trying to get you to stop posting redundant questions.

                You obviously don't want any help. And this is the last post you get from me, ever!


                Over here:

                http://www.jboss.com/index.html?module=bb&op=viewtopic&t=63795

                you imply that this item is in the FAQ. Where is this FAQ entry? I don't see it in here:


                From the FAQ (there aren't that many to read!):
                http://wiki.jboss.org/wiki/Wiki.jsp?page=WhatDoesTheMessageDoYourOwnHousekeepingMean


                Thread Local Patterns

                Many persistent frameworks (hibernate/ojb) open and close connections "at random". i.e. As far as JBoss is concerned it looks like one ejb allocated the connection and another closed it.

                The connection close checking does not understand this behaviour. It expects the same ejb that allocated the connection to also close it.

                If you use such a pattern, you can turn off this message (see below) but you are on your own when it comes to detecting connection leaks. From 3.2.6 there is a "listInUseConnections" on the CachedConnectionManager. However, there is this known issue with some transacion demarcation semantics. This is not really a JBoss use, more that ThreadLocal patterns bypass J2EE semantics. If you do hit the problem removing the CachedConnectionInterceptor from the conf/standardjboss.xml will workaround the spurious message. You can trust hibernate at least to close connections properly provided you ending user transactions correctly.


                • 5. Re: Need clarification: Trying to return an unknown connecti

                  And for completeness, though this is discussed ad infinitum elsewhere.

                  Thread local patterns are stupid. You can cause database connections to leak
                  across transaction boundaries with work getting done in random transactions.

                  Hibernate3 does not use this pattern, it uses the datasource pool as a .... pool.
                  TransactionLocal or sticky transaction connection caching is done by the j2ee
                  connection manager anyway!

                  in jboss:

                  <track-connection-by-tx/>
                  

                  enabled by default for local-tx-datasource and not really relevant for XA (unless the driver
                  doesn't support interleaving).

                  • 6. Re: Need clarification: Trying to return an unknown connecti

                    I (and I am sure uncountless others) thank you for finally answering this question.

                    Thi s information seems misplaced as only a footnote to a section entited "Thread Local Patterns" in a FAQ entry entitled "WhatDoesTheMessageDoYourOwnHousekeepingMean".

                    It seems a FAQ (or Wiki) entry saying: "Hibernate2 will cause spurious "Trying to return an unknown connection2" error messages due to incompatibility with J2EE spec" would be more approriate given how may times this question has been asked.

                    • 7. Re: Need clarification: Trying to return an unknown connecti

                       

                      "twalsh2" wrote:
                      I (and I am sure uncountless others) thank you for finally answering this question.

                      For the nth time.

                      The question was initially answered about 2 years ago and repeatedly
                      answered (and more often ignored) since then.
                      Including writing a testcase for the non-transaction-boundary-crossing usecase
                      to make sure it works properly.
                      http://anoncvs.forge.jboss.com/changelog/JBoss?cs=Branch_3_2:ejort:20030830150431


                      This information seems misplaced as only a footnote to a section entited "Thread Local Patterns" in a FAQ entry entitled "WhatDoesTheMessageDoYourOwnHousekeepingMean".


                      Then fix it. But, we can't have everything in the FAQ.
                      The whole question can be ignored if people just read the spec and followed it.


                      • 8. Re: Need clarification: Trying to return an unknown connecti

                        >The question was initially answered about 2 years ago and repeatedly
                        >answered (and more often ignored) since then.

                        Well I did a search for "Trying to return an unknown connection2", "Throwable from unregisterConnection" and various permutations and read through the result including linked JIRA entries.

                        Never once did I see the implications of removing the CachedConnectionInterceptor discussed nor a link to the "Thread Local Patterns" section of the "WhatDoesTheMessageDoYourOwnHousekeepingMean" FAQ entry.

                        In my own defence, I beleive I did my due diligence before asking for help.

                        >The whole question can be ignored if people just read the spec and followed it.

                        By "people" are you referring to the Hibernate team? I'm using Hibernate as its spelled out in the following Wiki entry: http://wiki.jboss.org/wiki/Wiki.jsp?page=JBossHibernate2. Is there something else I should be doing?

                        >Then fix it. But, we can't have everything in the FAQ.

                        I was unaware that regular users could contribute to the JBoss Wiki. I will look into it.

                        • 9. Re: Need clarification: Trying to return an unknown connecti

                           

                          "twalsh2" wrote:

                          By "people" are you referring to the Hibernate team?


                          Yes, I had a very long discussion with Gavin and Steve about a year ago about
                          why the thread local was a bad idea, and causes users problems :-)

                          • 10. Re: Need clarification: Trying to return an unknown connecti

                             

                            "adrian@jboss.org" wrote:
                            "twalsh2" wrote:

                            By "people" are you referring to the Hibernate team?


                            Yes, I had a very long discussion with Gavin and Steve about a year ago about
                            why the thread local was a bad idea, and causes users problems :-)


                            Although to be fair, Hibernate doesn't just run in JBoss,
                            so they have to deal with datasource implementations of dubious quality :-)

                            e.g. Gavin told me that JBoss is the only thing that implements prepared statement
                            caching properly. i.e. it resets the query configuration on "close()"

                            
                             public void close() throws SQLException
                             {
                             inUse.decrement();
                             if (inUse.get() == 0)
                             {
                             if (cached.get() == false)
                             ps.close();
                             else
                             {
                             // Reset the defaults
                             if (defaultMaxFieldSize != currentMaxFieldSize)
                             {
                             ps.setMaxFieldSize(defaultMaxFieldSize);
                             currentMaxFieldSize = defaultMaxFieldSize;
                             }
                             if (defaultMaxRows != currentMaxRows)
                             {
                             ps.setMaxRows(defaultMaxRows);
                             currentMaxRows = defaultMaxRows;
                             }
                             if (defaultQueryTimeout != currentQueryTimeout)
                             {
                             ps.setQueryTimeout(defaultQueryTimeout);
                             currentQueryTimeout = defaultQueryTimeout;
                             }
                             if (defaultFetchDirection != currentFetchDirection)
                             {
                             ps.setFetchDirection(defaultFetchDirection);
                             currentFetchDirection = defaultFetchDirection;
                             }
                             if (defaultFetchSize != currentFetchSize)
                             {
                             ps.setFetchSize(defaultFetchSize);
                             currentFetchSize = defaultFetchSize;
                             }
                             }
                             }
                             }
                            


                            • 11. Re: Need clarification: Trying to return an unknown connecti
                              mamgoncalves

                              Hi,

                              Hibernate 3 do not use the ?Thread Local? semantic, but uses a transaction listener to close the connection. I have created some code to behave like Hibernate.

                              The code has the follow semantic:
                              1) The client call a EJB method ?doThing? that have required transaction
                              2) The method ?doThing? gets a connection to the database and register a transaction listener that will close the connection
                              3) The method ?doThing? call another EJB method ?doOtherThinkOnDiferentTransacton? that have requires new transaction
                              4) The method ?doOtherThinkOnDiferentTransacton? gets a new connection to the database and register a transaction listener that will close the connection

                              When the method ?doOtherThinkOnDiferentTransacton? is over, the container invokes the transactions listeners and then the exception ?Trying to return an unknown connection2? is written to the log. If the step 2) is not done, the exception does not appear in the log.

                              Here is the code:

                              public class Connection2BugBean implements SessionBean {
                              public Connection2BugBean() {
                              // Empty
                              }

                              public void ejbCreate() throws CreateException {
                              // Empty
                              }

                              public void setSessionContext(SessionContext sessionContext) throws EJBException {
                              // Empty
                              }

                              public void ejbRemove() throws EJBException {
                              // Empty
                              }

                              public void ejbActivate() throws EJBException {
                              // Empty
                              }

                              public void ejbPassivate() throws EJBException {
                              // Empty
                              }

                              public void doThing() {
                              MyConnectionManager.getConnection();

                              try {
                              Context context = new InitialContext();
                              Connection2BugHome home = (Connection2BugHome) PortableRemoteObject.narrow(context.lookup("ejb/Connection2Bug"), Connection2BugHome.class);
                              Connection2Bug object = home.create();
                              object.doOtherThinkOnDiferentTransacton();
                              }
                              catch (Exception e) {
                              throw new RuntimeException(e);
                              }
                              }

                              public void doOtherThinkOnDiferentTransacton() {
                              MyConnectionManager.getConnection();
                              }

                              }

                              class MyConnectionManager implements Synchronization {
                              private static final Hashtable CONNECTIONS_BY_TRANSACTIONS = new Hashtable();
                              private static final Logger log = Logger.getLogger(Connection2BugBean.class);

                              private Transaction t;

                              public MyConnectionManager(Transaction t) {
                              this.t = t;
                              }

                              public static Connection getConnection() {
                              try {
                              Context context = new InitialContext();
                              TransactionManager tm = (TransactionManager) context.lookup("java:/TransactionManager");
                              Transaction t = tm.getTransaction();

                              Connection conn = (Connection) CONNECTIONS_BY_TRANSACTIONS.get(t);
                              if (conn == null) {
                              log.warn("Creating a connection binded to " + t);

                              DataSource ds = (DataSource) context.lookup("java:/DefaultDS");
                              conn = ds.getConnection();

                              CONNECTIONS_BY_TRANSACTIONS.put(t, conn);

                              t.registerSynchronization(new MyConnectionManager(t));
                              }

                              return conn;
                              }
                              catch (Exception e) {
                              throw new RuntimeException(e);
                              }
                              }

                              public void beforeCompletion() {
                              Connection conn = (Connection) CONNECTIONS_BY_TRANSACTIONS.remove(t);

                              if (conn != null) {
                              log.warn("Closing the connection binded to " + t);

                              try {
                              conn.close();
                              }
                              catch (Exception e) {
                              e.printStackTrace();
                              }
                              }
                              }

                              public void afterCompletion(int i) {
                              }
                              }