db-derby-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Mamta A. Satoor (JIRA)" <j...@apache.org>
Subject [jira] [Updated] (DERBY-6214) PreparedStatement.setObject(int, Object, Types.CLOB) fail with DerbyNet
Date Thu, 13 Jun 2013 06:42:20 GMT

     [ https://issues.apache.org/jira/browse/DERBY-6214?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]

Mamta A. Satoor updated DERBY-6214:
-----------------------------------

    Attachment: DERBY6214_patch2_diff.txt

Thanks for looking at the patch, Mike. I am attaching another patch which addresses most of
your comments. The files touched by this patch are as follows
$ svn stat -q
M       java\engine\org\apache\derby\iapi\reference\Limits.java
M       java\testing\org\apache\derbyTesting\functionTests\tests\jdbcapi\ParameterMappingTest.java
M       java\client\org\apache\derby\client\net\NetStatementRequest.java
M       java\client\org\apache\derby\client\am\CrossConverters.java
M       java\client\org\apache\derby\client\am\ClientPreparedStatement.java

This patch makes PreparedStatement.setObject work same as PreparedStatement.setString for
small strings(<=10922 characters in length). Additionally, I have modularized the tests
from the previous patch and made changes to verify the updated data for that test. The changes
to verify the updated data use ResultSet.getString and ResultSet.getObject thus verifying
that those apis work fine with the changed made for PreparedStatement.setObject. In addition,
I have added new tests for ResultSet.updateString and ResultSet.updateObject to make sure
the changes for PreparedStatement.setObject has not broken these apis since they share the
same code. I have added lot more comments into the code changes. I have also created a constant
in java\engine\org\apache\derby\iapi\reference\Limits.java for the length 10922 so in the
code, we use that constant rather than the actual number. I think it is ok to add the constant
in the Limits file since I have seen other client code using constants from that file.

Here is the response to some of the questions in your comments
********************************
 o you added the following with no comment as to why, I would prefer not to add an extra call
level to this high traffic routine if possible. Is it just to save some
       typing to change all the callse in the following setObject routine? If so I would just
rather see the code change made. all the overriding based on num arguments can 
       easily lead to bugs when making changes like this, other routine may start getting
called that you don't expect. :
    final Object setObject(int targetType, Object source) throws SqlException {
        return setObject(targetType, source, false);
    }

Yes, the reason for the new method is so that we don't have to change all the callers of CrossConverts.setObject(targetType,
source) to have to pass the new parameter which will be false for all except ClientPreparedStatement.setObjectX
method. I do see your point about this causing possible confusion and unintentional method
being called. I can go ahead and change all the callers to pass false when they call this
method and just have ClientPreparedStatement.setObjectX pass the value true. This will eliminate
the need for a new method in CrossConverts class.
********************************


********************************
4) what problems result if you don't have the originalSetObject information? It would be better
if we did not have the special case if we can help it, just always send string in small string
case.
    It seems likely there are existing problems with updateXXX also. maybe just is not right
for getXXX, not sure. I'd like to see if there is any way to fix this without adding a param/extra
call to
this high traffic routine.

When originally I didn't have the check in my code, it caused the existing junit test UpdatableResultSetTest
to fail. Now, that I have added ResultSet.updateXXX calls test in my junit test, I see the
same failure with that new junit test if I remove the originalSetObject information. The exception
is as follows. I have not spent the reason behind the class cast exception but I can spend
some time on it to see if it is easy to fix this exception so we do not need to have special
parameter originalSetObject anymore.
1) testDerby6214updateXXX(org.apache.derbyTesting.functionTests.tests.jdbcapi.ParameterMappingTest)java.lang.ClassCastException:
java.lang.String incompatible with java.sql.Clob
        at org.apache.derby.client.net.NetStatementRequest.computeProtocolTypesAndLengths(NetStatementRequest.java:1462)
        at org.apache.derby.client.net.NetStatementRequest.buildSQLDTAcommandData(NetStatementRequest.java:545)
        at org.apache.derby.client.net.NetStatementRequest.writeExecute(NetStatementRequest.java:162)
        at org.apache.derby.client.net.NetPreparedStatement.writeExecute_(NetPreparedStatement.java:156)
        at org.apache.derby.client.am.ClientResultSet.writeUpdateRow(ClientResultSet.java:4357)
        at org.apache.derby.client.am.ClientResultSet.positionToCurrentRowAndUpdate(ClientResultSet.java:4098)
        at org.apache.derby.client.am.ClientResultSet.updateRowX(ClientResultSet.java:3651)
        at org.apache.derby.client.am.ClientResultSet.updateRow(ClientResultSet.java:3555)
        at org.apache.derbyTesting.functionTests.tests.jdbcapi.ParameterMappingTest.testDerby6214updateXXX(ParameterMappingTest.java:439)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:60)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:37)
        at org.apache.derbyTesting.junit.BaseTestCase.runBare(BaseTestCase.java:117)
        at org.apache.derbyTesting.junit.BaseJDBCTestCase.runBareOverridable(BaseJDBCTestCase.java:439)
        at org.apache.derbyTesting.junit.BaseJDBCTestCase.runBare(BaseJDBCTestCase.java:456)
        at junit.extensions.TestDecorator.basicRun(TestDecorator.java:24)
        at junit.extensions.TestSetup$1.protect(TestSetup.java:21)
        at junit.extensions.TestSetup.run(TestSetup.java:25)
        at org.apache.derbyTesting.junit.BaseTestSetup.run(BaseTestSetup.java:57)
        at junit.extensions.TestDecorator.basicRun(TestDecorator.java:24)
        at junit.extensions.TestSetup$1.protect(TestSetup.java:21)
        at junit.extensions.TestSetup.run(TestSetup.java:25)
        at junit.extensions.TestDecorator.basicRun(TestDecorator.java:24)
        at junit.extensions.TestSetup$1.protect(TestSetup.java:21)
        at junit.extensions.TestSetup.run(TestSetup.java:25)
        at org.apache.derbyTesting.junit.BaseTestSetup.run(BaseTestSetup.java:57)
********************************

                
> PreparedStatement.setObject(int, Object, Types.CLOB) fail with DerbyNet
> -----------------------------------------------------------------------
>
>                 Key: DERBY-6214
>                 URL: https://issues.apache.org/jira/browse/DERBY-6214
>             Project: Derby
>          Issue Type: Bug
>    Affects Versions: 10.8.3.0, 10.9.1.0
>            Reporter: Rong Qu
>            Assignee: Mamta A. Satoor
>         Attachments: Derby6214.java, DERBY6214_patch1_diff.txt, DERBY6214_patch1_stat.txt,
DERBY6214_patch2_diff.txt, Derby6214_setup.sql, Derby6214_ver2.java, derby.log, DerbyNet_client_test.sql
>
>
> The issue is specific to the DerbyNet client driver, and doesn't seem to occur using
embedded Derby.
>  "PreparedStatement.setObject(int, Object, Types.CLOB)". It seems to be a problem updating
a CLOB column with a parameterized value using the DerbyNet client driver, and if the update
SQL ends up updating more than one row. I attached a simple test case that just uses JDBC
to reproduce the error. The exception looks like this:
> org.apache.derby.client.am.BatchUpdateException: Non-atomic batch failure.  The batch
was submitted, but at least one exception occurred on an individual member of the batch. Use
getNextException() to retrieve the exceptions for specific batched elements.
>     at org.apache.derby.client.am.Agent.endBatchedReadChain(Unknown Source)
>     at org.apache.derby.client.am.PreparedStatement.executeBatchRequestX(Unknown Source)
>     at org.apache.derby.client.am.PreparedStatement.executeBatchX(Unknown Source)
>     at org.apache.derby.client.am.PreparedStatement.executeBatch(Unknown Source)
>     ...
> Caused by: org.apache.derby.client.am.SqlException: Error for batch element #0: An unexpected
exception was thrown
>     at org.apache.derby.client.am.Statement.completeExecute(Unknown Source)
>     at org.apache.derby.client.net.NetStatementReply.parseEXCSQLSTTreply(Unknown Source)
>     at org.apache.derby.client.net.NetStatementReply.readExecute(Unknown Source)
>     at org.apache.derby.client.net.StatementReply.readExecute(Unknown Source)
>     at org.apache.derby.client.net.NetPreparedStatement.readExecute_(Unknown Source)
>     at org.apache.derby.client.am.PreparedStatement.readExecute(Unknown Source)
>     ... 4 more
> Caused by: org.apache.derby.client.am.SqlException: Error for batch element #0: Java
exception: 'Stream has already been read and end-of-file reached and cannot be re-used.: java.io.EOFException'.
>     at org.apache.derby.client.am.SqlException.<init>(Unknown Source)
>     at org.apache.derby.client.am.SqlException.<init>(Unknown Source)
>     ... 10 more

--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators
For more information on JIRA, see: http://www.atlassian.com/software/jira

Mime
View raw message