Return-Path: Delivered-To: apmail-ibatis-user-java-archive@www.apache.org Received: (qmail 76569 invoked from network); 29 Oct 2006 04:53:55 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.2) by minotaur.apache.org with SMTP; 29 Oct 2006 04:53:55 -0000 Received: (qmail 68686 invoked by uid 500); 29 Oct 2006 04:54:00 -0000 Delivered-To: apmail-ibatis-user-java-archive@ibatis.apache.org Received: (qmail 68664 invoked by uid 500); 29 Oct 2006 04:54:00 -0000 Mailing-List: contact user-java-help@ibatis.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: user-java@ibatis.apache.org Delivered-To: mailing list user-java@ibatis.apache.org Received: (qmail 68653 invoked by uid 99); 29 Oct 2006 04:54:00 -0000 Received: from herse.apache.org (HELO herse.apache.org) (140.211.11.133) by apache.org (qpsmtpd/0.29) with ESMTP; Sat, 28 Oct 2006 21:54:00 -0700 X-ASF-Spam-Status: No, hits=2.5 required=10.0 tests=DNS_FROM_RFC_ABUSE,HTML_MESSAGE,SPF_PASS X-Spam-Check-By: apache.org Received-SPF: pass (herse.apache.org: domain of clinton.begin@gmail.com designates 64.233.182.189 as permitted sender) Received: from [64.233.182.189] (HELO nf-out-0910.google.com) (64.233.182.189) by apache.org (qpsmtpd/0.29) with ESMTP; Sat, 28 Oct 2006 21:53:48 -0700 Received: by nf-out-0910.google.com with SMTP id l23so1820158nfc for ; Sat, 28 Oct 2006 21:53:26 -0700 (PDT) DomainKey-Signature: a=rsa-sha1; q=dns; c=nofws; s=beta; d=gmail.com; h=received:message-id:date:from:to:subject:in-reply-to:mime-version:content-type:references; b=BRJQMlOpE4c4tbT4Bd7auSmVgdOY0rT2KD8cl3YwRnfF0iAluDuQTjd243BLxO1O2o5bVjsWH/+hiCVOObEkU9JIC/IPF4RcrnbpDGm2HmK7AAgGBHWuOoFsEse0iFtLtjBDQUi4Gr5GPLAjY2N4J7cHwlQqwJkpGzmDQcgUQ1A= Received: by 10.48.242.19 with SMTP id p19mr2771174nfh; Sat, 28 Oct 2006 21:53:25 -0700 (PDT) Received: by 10.49.13.9 with HTTP; Sat, 28 Oct 2006 21:53:25 -0700 (PDT) Message-ID: <16178eb10610282153x52d5b9b7k4f2d22ed42842de3@mail.gmail.com> Date: Sat, 28 Oct 2006 22:53:25 -0600 From: "Clinton Begin" To: user-java@ibatis.apache.org Subject: Re: Statements being closed when they shouldn't be In-Reply-To: <16178eb10610272109h71c2ff53veb081126f08e15f2@mail.gmail.com> MIME-Version: 1.0 Content-Type: multipart/alternative; boundary="----=_Part_92295_14336152.1162097605371" References: <16178eb10610272109h71c2ff53veb081126f08e15f2@mail.gmail.com> X-Virus-Checked: Checked by ClamAV on apache.org ------=_Part_92295_14336152.1162097605371 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Content-Disposition: inline Just an FYI: This does NOT affect 2.2.0. The "hasPreparedStatement" code was added since then as part of the PreparedStatement caching. So I believe this is exactly the same issue Jeff posted a while back. I've fixed the problem and I'll be committing it within minutes. Clinton On 10/27/06, Clinton Begin wrote: > > > Thanks for all the debugging efforts. With this information, it should be > a snap to fix. > > Cheers, > Clinton > > On 10/27/06, Christopher.Mathrusse@sybase.com < > Christopher.Mathrusse@sybase.com> wrote: > > > > Yes, if I disable logging all together the error does not occur. I'm > > guessing that this is something that you have seen before. > > > > ------------------------------ > > *From:* "Jeff Butler" [mailto:"Jeff Butler" < > > jeffgbutler@gmail.com>] > > *Sent:* Friday, October 27, 2006 12:40 PM > > *To:* user-java@ibatis.apache.org > > *Subject:* Re: Statements being closed when they shouldn't be > > > > Maybe. > > > > Chris - can you verify whether the behavior changes if you disable > > logging? > > > > Also, you can disable caching completely by altering the methods in > > com.ibatis.sqlmap.engine.scope.SessionScope to always return false. > > > > Jeff Butler > > > > > > On 10/27/06, Clinton Begin wrote: > > > > > > Yeah, let's open a JIRA issue.... > > > > > > JEFF: Could this be the same problem with the prepared statement > > > caching when logging is enabled? > > > > > > Cheers, > > > Clinton > > > > > > On 10/27/06, Christopher.Mathrusse@sybase.com < > > > Christopher.Mathrusse@sybase.com> wrote: > > > > > > > > Hi Clinton, > > > > I've run into a bit of a snag in the SqlExecutor class, > > > > closeStatement method. (Line 501) It seems that this class caches statements > > > > within the session object. In the closeStatement method there is an > > > > evaluation: > > > > > > > > if (!session.hasPreparedStatement(ps)) { > > > > if (ps != null) { > > > > try { > > > > ps.close(); > > > > } catch (SQLException e) { > > > > // ignore > > > > } > > > > } > > > > } > > > > The problem that I'm seeing is that the PreparedStatement is being > > > > closed every time. This is due to the fact that the actual PreparedStatement > > > > is wrapped within a PreparedStatementLogProxy object. When the > > > > evaluation is made above, session.hasPreparedStatement(ps), the > > > > session is asking the preparedStatements HashMap if it contains a value, > > > > namely the PreparedStatementLogProxy. When the map iterates through the > > > > objects it contains the equals() method is invoked on each object. This is > > > > where the problem lies. > > > > > > > > Invoking equals() causes the invoke method of the PreparedStatementLogProxy > > > > to intercept the call. Evaluations are made within this method until the > > > > following method is invoked, allowing the underlying equals method on the > > > > PreparedStatement to be invoked. > > > > > > > > *return* method.invoke(statement, params); > > > > > > > > The problem here is that the actual PreparedStatement is being > > > > passed in for comparison with an instance of PreparedStatementLogProxy. This > > > > always results in evaluating to false. Even if you were to compare an > > > > instance of the Proxy with itself, ps.equals(ps), the result will be > > > > false. I verified this by setting a breakpoint in the SqlExecutor class and > > > > ran this evaluation which resulted in false. > > > > > > > > I don't have a solution to this unfortunately. I first thought a > > > > simple comparison of the parameter object being an instanceof PreparedStatementLogProxy, > > > > but that also returns false, as does PreparedStatementLogProxy.* > > > > class*.isAssignableFrom(params[0].getClass()). > > > > > > > > My problem is that the Statements are always being close when they > > > > should not be and this is resulting in errors being raised from the JDBC > > > > layer because the Statement is being closed more than once. This is because > > > > when SqlMapSessionImpl.close() is called the delegate, SqlMapExecutorDelegate > > > > pushSession method is called. In here session.reset() is called > > > > which closes any PreparedStatements that it contains. Effectively closing > > > > the PreparedStatement twice. > > > > > > > > Should I open an JIRA on this? > > > > > > > > Chris Mathrusse > > > > christopher.mathrusse@sybase.com > > > > (925) 236-5553 > > > > > > > > > > > > > > > > > ------=_Part_92295_14336152.1162097605371 Content-Type: text/html; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit Content-Disposition: inline Just an FYI:  This does NOT affect 2.2.0.  The "hasPreparedStatement" code was added since then as part of the PreparedStatement caching.  So I believe this is exactly the same issue Jeff posted a while back. 

I've fixed the problem and I'll be committing it within minutes.

Clinton

On 10/27/06, Clinton Begin < clinton.begin@gmail.com> wrote:

Thanks for all the debugging efforts. With this information, it should be a snap to fix. 


Cheers,
Clinton

On 10/27/06, Christopher.Mathrusse@sybase.com <Christopher.Mathrusse@sybase.com> wrote:
Yes, if I disable logging all together the error does not occur. I'm guessing that this is something that you have seen before.


From: "Jeff Butler" <jeffgbutler@gmail.com> [mailto:"Jeff Butler" <jeffgbutler@gmail.com>]
Sent: Friday, October 27, 2006 12:40 PM
To: user-java@ibatis.apache.org
Subject: Re: Statements being closed when they shouldn't be

Maybe.
 
Chris - can you verify whether the behavior changes if you disable logging?
 
Also, you can disable caching completely by altering the methods in com.ibatis.sqlmap.engine.scope.SessionScope to always return false.
 
Jeff Butler

 
On 10/27/06, Clinton Begin <clinton.begin@gmail.com> wrote:
Yeah, let's open a JIRA issue....

JEFF:  Could this be the same problem with the prepared statement caching when logging is enabled?

Cheers,
Clinton


On 10/27/06, Christopher.Mathrusse@sybase.com <Christopher.Mathrusse@sybase.com> wrote:
Hi Clinton,
I've run into a bit of a snag in the SqlExecutor class, closeStatement method. (Line 501) It seems that this class caches statements within the session object. In the closeStatement method there is an evaluation:
 
    if (!session.hasPreparedStatement(ps)) {
      if (ps != null) {
        try {
          ps.close();
        } catch (SQLException e) {
          // ignore
        }
      }
    }
The problem that I'm seeing is that the PreparedStatement is being closed every time. This is due to the fact that the actual PreparedStatement is wrapped within a PreparedStatementLogProxy object. When the evaluation is made above, session.hasPreparedStatement(ps), the session is asking the preparedStatements HashMap if it contains a value, namely the PreparedStatementLogProxy. When the map iterates through the objects it contains the equals() method is invoked on each object. This is where the problem lies.
 
Invoking equals() causes the invoke method of the PreparedStatementLogProxy to intercept the call. Evaluations are made within this method until the following method is invoked, allowing the underlying equals method on the PreparedStatement to be invoked.

return method.invoke(statement, params);

The problem here is that the actual PreparedStatement is being passed in for comparison with an instance of PreparedStatementLogProxy. This always results in evaluating to false. Even if you were to compare an instance of the Proxy with itself, ps.equals(ps), the result will be false. I verified this by setting a breakpoint in the SqlExecutor class and ran this evaluation which resulted in false.

I don't have a solution to this unfortunately. I first thought a simple comparison of the parameter object being an instanceof PreparedStatementLogProxy, but that also returns false, as does PreparedStatementLogProxy.class.isAssignableFrom(params[0].getClass()).

My problem is that the Statements are always being close when they should not be and this is resulting in errors being raised from the JDBC layer because the Statement is being closed more than once. This is because when SqlMapSessionImpl.close() is called the delegate, SqlMapExecutorDelegate pushSession method is called. In here session.reset() is called which closes any PreparedStatements that it contains. Effectively closing the PreparedStatement twice.

Should I open an JIRA on this?

 
Chris Mathrusse
(925) 236-5553
 




------=_Part_92295_14336152.1162097605371--