Issue Details (XML | Word | Printable)

Key: DBUTILS-31
Type: Improvement Improvement
Status: Closed Closed
Resolution: Fixed
Priority: Major Major
Assignee: Dan Fabulich
Reporter: Francis Townsend
Votes: 0
Watchers: 0
Operations

If you were logged in you would be able to see more operations.
Commons DbUtils

fillStatement setNull bug with the Derby JDBC driver

Created: 13/Jun/06 07:45 AM   Updated: 07/Mar/09 06:09 AM
Return to search
Component/s: None
Affects Version/s: 1.0
Fix Version/s: 1.2

Time Tracking:
Not Specified

Environment: Derby 10.1.2.1

Resolution Date: 25/Feb/09 10:05 AM


 Description  « Hide
This has been documented many times before, but I was not happy with the existing code fixes. The following small code snippet should fix it for all conforming JDBC drivers.
protected void fillStatement(PreparedStatement stmt, Object[] params)
        throws SQLException {

        if (params == null) {
            return;
        }
        ParameterMetaData pmd = stmt.getParameterMetaData();
        for (int i = 0; i < params.length; i++) {
            if (params[i] != null) {
                stmt.setObject(i + 1, params[i]);
            } else {
                stmt.setNull(i + 1, pmd.getParameterType(i + 1));
            }
        }
    }

The only difference is that you get the parameter meta data and pass that type information to the setNull method. This should neatly fix this problem, with a very slight additional overhead.



 All   Comments   Work Log   Change History   Subversion Commits      Sort Order: Ascending order - Click to sort in descending order
Henri Yandell added a comment - 06/Jul/06 01:40 PM
Evaluate for 1.1.

Henri Yandell made changes - 06/Jul/06 01:40 PM
Field Original Value New Value
Fix Version/s 1.1 [ 12311973 ]
Francis Townsend added a comment - 07/Jul/06 02:22 AM
This code was coded for the JDBC 3.0 specification. It would need to be modified to run with JDBC 2.1 drivers (check the JDBCMajor version to determine which code to use).

Also, I have read that the Oracle JDBC driver throws an Exception. Unfortunately, it does not look as if there is no method that can determine this before calling the getParameterType method. Which means we would need to catch the exception and role back to the previous code, namely use the VARCHAR type when setting null. This would always be thrown by the Oracle driver, severely slowing it down.

So, I would suggest we hold off putting this into the next release until we have a better solution.


Henri Yandell made changes - 02/Nov/06 06:18 AM
Fix Version/s 1.1 [ 12311973 ]
Dennis Lundberg made changes - 16/Mar/08 09:35 PM
Description This has been documented many times before, but I was not happy with the existing code fixes. The following small code snippet should fix it for all conforming JDBC drivers.

    protected void fillStatement(PreparedStatement stmt, Object[] params)
        throws SQLException {

        if (params == null) {
            return;
        }
        ParameterMetaData pmd = stmt.getParameterMetaData();
        for (int i = 0; i < params.length; i++) {
            if (params[i] != null) {
                stmt.setObject(i + 1, params[i]);
            } else {
                stmt.setNull(i + 1, pmd.getParameterType(i + 1));
            }
        }
    }

The only difference is that you get the parameter meta data and pass that type information to the setNull method. This should neatly fix this problem, with a very slight additional overhead.
This has been documented many times before, but I was not happy with the existing code fixes. The following small code snippet should fix it for all conforming JDBC drivers.

{code}
    protected void fillStatement(PreparedStatement stmt, Object[] params)
        throws SQLException {

        if (params == null) {
            return;
        }
        ParameterMetaData pmd = stmt.getParameterMetaData();
        for (int i = 0; i < params.length; i++) {
            if (params[i] != null) {
                stmt.setObject(i + 1, params[i]);
            } else {
                stmt.setNull(i + 1, pmd.getParameterType(i + 1));
            }
        }
    }
{code}

The only difference is that you get the parameter meta data and pass that type information to the setNull method. This should neatly fix this problem, with a very slight additional overhead.
Liam Seamus Coughlin added a comment - 12/Jan/09 03:28 PM
I think this is the best of the proposed solutions – it's certainly the simplest, and given that future versions of dbutils will be focusing on java 5+ I don't think we should be worrying about ancient versions of JDBC.

Dan Fabulich added a comment - 08/Feb/09 10:07 PM
Unfortunately, Oracle 10.2 JDBC drivers still don't support getParameterMetaData, even as recently as Oct 2008. http://forums.oracle.com/forums/thread.jspa?threadID=585880

You have to register to read that link (it's free but it's a hassle). But the most recent post is confirming that it's still broken in Oct 2008. If you call getParameterType, you get error ORA-17023 "Unsupported feature." Lame!


Repository Revision Date User Message
ASF #742865 Tue Feb 10 06:41:05 UTC 2009 dfabulich [DBUTILS-14] [DBUTILS-31] [DBUTILS-39] [DBUTILS-41] [DBUTILS-44] setNull problems with Postgres and Oracle.

With this change, we now attempt to use ParameterMetaData.getParameterType to determine the SQL type of a null parameter. On Oracle, this will fail, so we'll try it once (at most), and record the failure in a volatile boolean so we won't try it again unnecessarily.
Files Changed
MODIFY /commons/sandbox/dbutils/bugfixing/src/java/org/apache/commons/dbutils/QueryRunner.java

Repository Revision Date User Message
ASF #747724 Wed Feb 25 10:01:31 UTC 2009 bayard Merging in Dab Fabulich's work on https://svn.apache.org/repos/asf/commons/sandbox/dbutils/bugfixing from -r741987:747723. Resolving DBUTILS-34 - DBUTILS-37 - DBUTILS-29 - DBUTILS-14 - DBUTILS-31 - DBUTILS-39 - DBUTILS-41 - DBUTILS-44 - DBUTILS-33 - DBUTILS-42 - DBUTILS-40
Files Changed
MODIFY /commons/proper/dbutils/trunk/src/java/org/apache/commons/dbutils/handlers/MapListHandler.java
MODIFY /commons/proper/dbutils/trunk/src/java/org/apache/commons/dbutils/BasicRowProcessor.java
MODIFY /commons/proper/dbutils/trunk/src/java/org/apache/commons/dbutils/handlers/BeanListHandler.java
MODIFY /commons/proper/dbutils/trunk/src/java/org/apache/commons/dbutils/BeanProcessor.java
ADD /commons/proper/dbutils/trunk/src/java/org/apache/commons/dbutils/handlers/AbstractListHandler.java (from /commons/sandbox/dbutils/bugfixing/src/java/org/apache/commons/dbutils/handlers/AbstractListHandler.java)
MODIFY /commons/proper/dbutils/trunk/src/test/org/apache/commons/dbutils/BaseTestCase.java
MODIFY /commons/proper/dbutils/trunk/pom.xml
MODIFY /commons/proper/dbutils/trunk/src/java/org/apache/commons/dbutils/handlers/ColumnListHandler.java
DEL /commons/proper/dbutils/trunk/src/java/org/apache/commons/dbutils/handlers/GenericListHandler.java
ADD /commons/proper/dbutils/trunk/src/test/org/apache/commons/dbutils/QueryRunnerTest.java (from /commons/sandbox/dbutils/bugfixing/src/test/org/apache/commons/dbutils/QueryRunnerTest.java)
MODIFY /commons/proper/dbutils/trunk/src/java/org/apache/commons/dbutils/handlers/ArrayListHandler.java
MODIFY /commons/proper/dbutils/trunk/src/java/org/apache/commons/dbutils/QueryRunner.java

Henri Yandell added a comment - 25/Feb/09 10:05 AM
svn ci -m "Merging in Dab Fabulich's work on https://svn.apache.org/repos/asf/commons/sandbox/dbutils/bugfixing from -r741987:747723. Resolving DBUTILS-34 - DBUTILS-37 - DBUTILS-29 - DBUTILS-14 - DBUTILS-31 - DBUTILS-39 - DBUTILS-41 - DBUTILS-44 - DBUTILS-33 - DBUTILS-42 - DBUTILS-40"

Sending pom.xml
Sending src/java/org/apache/commons/dbutils/BasicRowProcessor.java
Sending src/java/org/apache/commons/dbutils/BeanProcessor.java
Sending src/java/org/apache/commons/dbutils/QueryRunner.java
Adding src/java/org/apache/commons/dbutils/handlers/AbstractListHandler.java
Sending src/java/org/apache/commons/dbutils/handlers/ArrayListHandler.java
Sending src/java/org/apache/commons/dbutils/handlers/BeanListHandler.java
Sending src/java/org/apache/commons/dbutils/handlers/ColumnListHandler.java
Deleting src/java/org/apache/commons/dbutils/handlers/GenericListHandler.java
Sending src/java/org/apache/commons/dbutils/handlers/MapListHandler.java
Sending src/test/org/apache/commons/dbutils/BaseTestCase.java
Adding src/test/org/apache/commons/dbutils/QueryRunnerTest.java
Transmitting file data .........
Committed revision 747724.


Henri Yandell made changes - 25/Feb/09 10:05 AM
Resolution Fixed [ 1 ]
Fix Version/s 1.2 [ 12312139 ]
Status Open [ 1 ] Closed [ 6 ]
Dan Fabulich made changes - 07/Mar/09 06:09 AM
Assignee Dan Fabulich [ dfabulich ]