4

I upgraded oracle and ojdbc versions from 11.1.0.2 to 12.1.0.2. I want to give an array of oracle object types as a parameter to an oracle procedure. This procedure takes 2 varchar2 parameters on oracle side. For example, I am sending 3 objects as an array of key-value pairs and oracle accepts these objects. My problem is that the parameters (of varchar2 type) are null, when calling my procedure.

Here is the code I have tried.

OracleConnection oraconn = conn.unwrap(OracleConnection.class);
Struct[] paramStructArray = new Struct[3];
paramStructArray[0] = oraconn.createStruct("KEY_VALUE_ENTRY",new Object[]{"key1","value1"});
paramStructArray[1] = oraconn.createStruct("KEY_VALUE_ENTRY",new Object[]{"key2","value2"});
paramStructArray[2] = oraconn.createStruct("KEY_VALUE_ENTRY",new Object[]{"key3","value3"});
Array array = oraconn.createOracleArray("KEY_VALUE_MAP", paramStructArray);

CallableStatement cstmt = getStatement(Statement.REGISTER_REQUEST);
cstmt.setString(1, requestId);
cstmt.setArray(2, array);
cstmt.execute();

This is my java code and here is also my oracle objects


CREATE OR REPLACE TYPE "KEY_VALUE_ENTRY"  AS
OBJECT (
  key VARCHAR2(32),
  val VARCHAR2(2048)
);


CREATE OR REPLACE TYPE "KEY_VALUE_MAP"    AS
TABLE OF key_value_entry;

and my procedure

PROCEDURE register_request_(p_request_id IN varchar2
                             ,p_params     IN key_value_map) AS
  BEGIN
    IF p_params IS NOT NULL THEN
      INSERT INTO test_table
        (request, NAME, VALUE)
        SELECT test_seq.nextval
              ,t.key
              ,t.val
          FROM TABLE(CAST(p_params AS key_value_map)) t;
      COMMIT;
  END IF;
  EXCEPTION
    WHEN OTHERS THEN
      RAISE;
  END;

I am taking 3 KEY_VALUE_ENTRY type objects on oracle side but this objects' key and val fields are both null. I can not figure out what I am doing wrong.

7
  • Did this work as expected before the upgrade? Just check as I dont know if it did or didnt? Commented Jun 17, 2019 at 7:49
  • Yes it worked before update, but the code was little different, There was classes like STRUCT , ARRAY and ArrayDescriptor which are deprecated on this version of ojdbc Commented Jun 17, 2019 at 7:53
  • You may have to rewrite a lot then I would suspect, What I would do is revert the code back to its working form and then step by step replace each section all the while debugging it. So make a change debug make a change debug. Its a little tedious, but I think that you can find where the issues are Commented Jun 17, 2019 at 7:56
  • This is the best I could find, and I still don't think it answers your question. stackoverflow.com/questions/37160300/… Commented Jun 17, 2019 at 8:09
  • This is what i exactly want and doing same, but for some reason it does not work stackoverflow.com/questions/19888520/… Commented Jun 17, 2019 at 8:10

2 Answers 2

2

There was Encoding problem, in which java gives and oracle takes this values, after adding orai18n.jar in my classpath everything works fine

Sign up to request clarification or add additional context in comments.

Comments

0

I tried this code and it works as expected without adding orai18n.jar to classpath. I kept db methods as they are.

public void insertTable(List<KeyValueObj> list, Connection conn)
            throws SQLException {
        String str = "{call Test_schema.Test_pkg.Register_Request(?,?)}";
        OracleCallableStatement statement = null;
        OracleConnection oraConn = null;
        String requestId = "111";
        try{
            oraConn = conn.unwrap(OracleConnection.class);
            statement = (OracleCallableStatement) oraConn.prepareCall(str);
            statement.setObject(2, getOracleRowObjectList(list, oraConn));
            statement.setString(1,requestId);
            statement.execute();
        }finally {
            try {
                statement.close();
                } catch (Exception e) {

            }
        }

    }

     private Array getOracleRowObjectList(List<KeyValueObj> list, OracleConnection conn) throws SQLException{
        String type = "Test_schema.KEY_VALUE_MAP";
        Struct[] structList = new Struct[list.size()];

        for(int i=0;i<list.size();i++){
            structList[i] = getOracleRowObject(conn, list.get(i));
        }

        return conn.createOracleArray(type, structList);
    }


    private Struct getOracleRowObject(OracleConnection conn, KeyValueObj obj) throws SQLException{
        String typeRow = "Test_schema.KEY_VALUE_ENTRY";
        return conn.createStruct(typeRow,
                new Object[]{ obj.getKey(),
                              obj.getValue(),

        });
    }

KeyValueObj class

public class KeyValueObj {
    private String key;
    private String value;

    public KeyValueObj(String key, String value) {
        super();
        this.key = key;
        this.value = value;
    }

    public String getKey() {
        return key;
    }
    public void setKey(String key) {
        this.key = key;
    }
    public String getValue() {
        return value;
    }
    public void setValue(String value) {
        this.value = value;
    }   

}

Hope, this would help someone facing the same issue.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.