Skip to content

org.h2.jdbc.JdbcConnection.getTypeMap() returns null #4010

@errael

Description

@errael

The program at the end of this gets

java.sql.SQLException: Cannot instantiate a SerialArray object with null parameters
	at java.sql.rowset/javax.sql.rowset.serial.SerialArray.<init>(SerialArray.java:152)

In CachedRowSetWriter.updateOriginalRow there's

Map<String, Class<?>> map = (crs.getTypeMap() == null)?con.getTypeMap():crs.getTypeMap();

This looks like a bug in org.h2.jdbc.JdbcConnection:

public Map<String, Class<?>> getTypeMap() throws SQLException {
    ...
    return null;

The documentation for Connection.getTypeMap() says:

Unless the application has added an entry, the type map returned will be empty. 

The test program also shows a workaround,

rs.setTypeMap(Collections.emptyMap());
package play.syncerror;

import java.io.StringReader;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Collections;

import javax.sql.RowSet;
import javax.sql.rowset.CachedRowSet;
import javax.sql.rowset.RowSetProvider;

import org.h2.tools.RunScript;

/** */
public class ConnectionTypeMap
{
    void doit() throws ClassNotFoundException, SQLException
    {
        //String url = "jdbc:h2:mem:suppliers_and_parts;TRACE_LEVEL_SYSTEM_OUT=3";
        String url = "jdbc:h2:mem:suppliers_and_parts";

        boolean use_crs = true;
        boolean use_workaround = false;

        Class.forName("org.h2.Driver");
        Connection conn = DriverManager.getConnection(url);
        RunScript.execute(conn, new StringReader(createDB));

        System.err.printf("########### use_crs: %s, use_workaround: %s\n",
                          use_crs, use_workaround);

        RowSet rs;
        if (use_crs) {
            rs = RowSetProvider.newFactory().createCachedRowSet();
        } else {
            rs = RowSetProvider.newFactory().createJdbcRowSet();
        }

        if (use_workaround)
            rs.setTypeMap(Collections.emptyMap());

        rs.setUrl(url);
        rs.setCommand("SELECT * FROM swingset_base_test_data");
        rs.execute();
        rs.first();
        Object o = rs.getObject(2);
        System.err.printf("########### %s\n", o);
        rs.updateString(2, "xxx");
        rs.updateRow();

        if (use_crs)
            ((CachedRowSet)rs).acceptChanges();

        rs.execute();
        rs.first();
        o = rs.getObject(2);
        System.err.printf("########### %s\n", o);
    }

    String createDB =
      "CREATE SEQUENCE IF NOT EXISTS swingset_base_test_seq START WITH 1000;\n"
    + "CREATE TABLE IF NOT EXISTS swingset_base_test_data \n"
    + "( \n"
    + "    swingset_base_test_pk INTEGER DEFAULT nextval('swingset_base_test_seq') NOT NULL PRIMARY KEY,\n"
    + "    ss_text_field VARCHAR(100),\n"
    + "    ss_list INTEGER ARRAY\n"
    + ");\n"
    + "MERGE INTO swingset_base_test_data VALUES (1,'This is TextField 1',ARRAY[1,2,3]) ;\n"
    + "MERGE INTO swingset_base_test_data VALUES (2,'This is TextField 2',ARRAY[3,4,5]) ;\n";
    

    public static void main(String[] args)
            throws ClassNotFoundException, SQLException
    {
        new ConnectionTypeMap().doit();
    }

}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions