ibatis-user-java mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Christopher.Mathru...@sybase.com
Subject RE: Odd behavior in SqlExecutor
Date Wed, 27 Sep 2006 21:26:18 GMT
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML><HEAD>
<META http-equiv=Content-Type content="text/html; charset=us-ascii" html; text 
Content-Type:>
<META content="MSHTML 6.00.2900.2963" name=GENERATOR></HEAD>
<BODY>
<DIV dir=ltr align=left><SPAN class=093142121-27092006><FONT color=#0000ff

size=2>I think I found it. The $Proxy97 class is a java.lang.reflect.Proxy 
instance and the&nbsp;problem lies in the class </FONT><FONT color=#0000ff><FONT

size=2><STRONG><EM>com.ibatis.common.jdbc.logging</EM></STRONG><SPAN

class=093142121-27092006><STRONG><EM>.</EM></STRONG><FONT 
size=2><STRONG><EM>PreparedStatementLogProxy. </EM></STRONG>When
the equals 
method is invoked control is being passed to this class. The 
<STRONG><EM>invoke</EM></STRONG> method is being called and control
falls down 
to line 80, where the method is being invoked, passing in the statement and the 
params. The passed in statement is an instance of 
<STRONG><EM>SybPreparedStatement</EM></STRONG> but params[0] is an
instance of 
<STRONG><EM>$Proxy97</EM></STRONG> so of course they are not equal,
and this is 
why the PreparedStatement is never found within the 
session.</FONT></SPAN></FONT></FONT></SPAN></DIV><BR>
<DIV class=OutlookMessageHeader lang=en-us dir=ltr align=left>
<HR tabIndex=-1>
<FONT face=Tahoma size=2><B>From:</B> Christopher.Mathrusse@sybase.com 
[mailto:Christopher.Mathrusse@sybase.com] <BR><B>Sent:</B> Wednesday, September

27, 2006 2:09 PM<BR><B>To:</B> user-java@ibatis.apache.org<BR><B>Subject:</B>

Odd behavior in SqlExecutor<BR></FONT><BR></DIV>
<DIV></DIV>
<META content="MSHTML 6.00.2900.2963" name=GENERATOR>
<DIV><SPAN class=249383720-27092006><FONT size=2>I'm using:</FONT></SPAN></DIV>
<DIV><SPAN class=249383720-27092006><FONT size=2>the latest version of iBatis.

(Compiled it from svn last week)</FONT></SPAN></DIV>
<DIV><SPAN class=249383720-27092006><FONT size=2>Spring 2.0 
rc4</FONT></SPAN></DIV>
<DIV><SPAN class=249383720-27092006><FONT size=2>Sybase ASE 
12.5</FONT></SPAN></DIV>
<DIV><SPAN class=249383720-27092006><FONT size=2></FONT></SPAN>&nbsp;</DIV>
<DIV><SPAN class=249383720-27092006><FONT size=2>I'm seeing some rather
odd 
behavior that I can't explain. The only reason I found this is due to the fact 
that I've turned on JDBC trace in the JDBC driver. On occasion I see in the 
trace file SQL Exceptions occurring due to the Object already being closed. I 
traced this down to the fact that the PreparedStatement was being closed twice. 
As I traced this down I found the code in Spring where the exception was 
actually being consumed as the exception is occurring on a call to 
PreparedStatement.close(). (Of course this is negligible)&nbsp; 
</FONT></SPAN><SPAN class=249383720-27092006><FONT size=2>So I decided
to 
investigate a bit more to see why it was being called twice. 
</FONT></SPAN></DIV>
<DIV><SPAN class=249383720-27092006><FONT size=2></FONT></SPAN>&nbsp;</DIV>
<DIV><SPAN class=249383720-27092006><FONT size=2>I found within the 
class&nbsp;</FONT><FONT size=2>com.ibatis.sqlmap.engine.execution<SPAN

class=249383720-27092006>.SqlExecutor where the problem stems from. The method 
on line 481</SPAN></FONT></SPAN></DIV>
<DIV><SPAN class=249383720-27092006><FONT size=2><SPAN 
class=249383720-27092006><FONT size=2>
<P align=left></FONT><B><FONT color=#7f0055 size=2>private</B></FONT><FONT

size=2> </FONT><B><FONT color=#7f0055 size=2>static</B></FONT><FONT
size=2> 
PreparedStatement prepareStatement(SessionScope session, Connection conn, String 
sql) </FONT><B><FONT color=#7f0055 size=2>throws</B></FONT><FONT
size=2> 
SQLException </P></FONT></SPAN></FONT></SPAN></DIV>
<DIV><SPAN class=249383720-27092006><FONT size=2>checks to see if a 
PreparedStatement already exists in the session and if not it creates the 
PreparedStatement and places it into the session, so it can be found later. 
(That make sense) The session simply places it into a HashMap called 
preparedStatements. I can see the newly created PreparedStatement in the 
session. (Object Id's match) The statement is then returned to 
the&nbsp;executeQuery method and it's business as usual. The statement is 
executed, the results are processed, everything is normal. Then in the finally 
block the resultSet is closed and then the method closeStatement is executed, 
passing in the session and the PreparedStatement.</FONT></SPAN></DIV>
<DIV><FONT size=2></FONT>&nbsp;</DIV>
<DIV><FONT size=2>W<SPAN class=249383720-27092006>ithin this method, line
501, a 
test is made to see if the session contains the PreparedStatement. 
</SPAN></FONT></DIV>
<DIV><SPAN class=249383720-27092006>
<P align=left><B><FONT color=#7f0055><FONT size=2>if</FONT></B></FONT><FONT

size=2> (!session.hasPreparedStatement(ps))</FONT></P>
<P align=left><SPAN class=249383720-27092006><FONT size=2>If the session
does 
not contain the statement, then the statement is closed, and this is the 
behavior I'm seeing. The statement is being closed. The problem is though that 
the session does contain the statement. The object Id's match up, the passed in 
PreparedStatement and the object residing in the session's preparedStatements 
HashMap. </FONT></SPAN></P>
<P align=left><SPAN class=249383720-27092006><FONT size=2>If I execute <FONT

size=2><STRONG><EM>session.hasPreparedStatementFor(String)</EM></STRONG>
it 
returns true, it finds the entry, but if I execute <FONT 
size=2><STRONG><EM>session.hasPreparedStatement(ps)&nbsp;</EM></STRONG>it

returns false. And because it returns false the PreparedStatement is being 
closed. Interestingly enough, when I execute 
<STRONG><EM>session.getPreparedStatement(String).equals(ps) </EM></STRONG>the

return value is false, which simply confuses me. 
</FONT></FONT></FONT></SPAN></P>
<P align=left><SPAN class=249383720-27092006><FONT size=2>Looking at the

PreparedStatement I can see that the object is of datatype $Proxy97. I believe 
that this is because the PreparedStatement is being wrapped in a similar fashion 
to the Connection itself. My guess at this point would be that the Proxy is not 
implementing the equals() method correctly and that is why I am seeing this 
behavior. (Does this sound plausible?)</FONT></SPAN></P>
<P align=left><SPAN class=249383720-27092006><FONT size=2>So I'm guessing
that I 
need to figure out who is wrapping the underlying PreparedStatement. (Spring? 
The Transaction Manager?) </FONT></SPAN></P>
<P align=left><SPAN class=249383720-27092006><FONT size=2>Any insight or
wisdom 
into this issue will be greatly appreciated. </FONT></SPAN></P>
<P align=left><SPAN class=249383720-27092006><FONT 
size=2>Thanks....</FONT></P></SPAN>
<P align=left><SPAN class=249383720-27092006><FONT 
size=2></FONT></SPAN>&nbsp;</P>
<P align=left><FONT size=2></FONT>&nbsp;</P></SPAN></DIV>
<DIV><SPAN class=249383720-27092006><FONT size=2></FONT></SPAN><FONT

size=2></FONT>&nbsp;</DIV>
<DIV align=left><FONT size=2>Chris Mathrusse</FONT></DIV>
<DIV align=left><FONT size=2><A 
href="mailto:christopher.mathrusse@sybase.com">christopher.mathrusse@sybase.com</A></FONT></DIV>
<DIV align=left><FONT size=2>(925) 236-5553</FONT></DIV>
<DIV>&nbsp;</DIV></BODY></HTML>


Mime
View raw message