c3p0和Oracle对象类型问题

时间:2011-09-16 08:18:01

标签: java arrays oracle c3p0

有几个使用jdbc和Oracle 10g的应用程序。现在我正在更改使用c3p0的应用程序。但是我在使用Oracle类型时遇到了一些问题。

我有这种Oracle类型:

CREATE OR REPLACE
TYPE DATAOBJ AS OBJECT
(
  ID NUMBER,
  NAME VARCHAR2(50)
) 

这个Oracle函数:

    CREATE OR REPLACE FUNCTION F_IS_DATA_OBJECT (datar in DATAOBJ) RETURN varchar2 IS
    tmpVar varchar2(150);
    BEGIN
        tmpVar := 'Data object:';
        if datar.id is not null then
            tmpVar := tmpVar || 'id=' || datar.ID;
        end if;

        if datar.name is not null then
            tmpVar := tmpVar || 'name=' || datar.name;
        end if;


    return tmpVar;          

   EXCEPTION
     WHEN NO_DATA_FOUND THEN
       NULL;
     WHEN OTHERS THEN
       RAISE;
END F_IS_DATA_OBJECT;

然后我有一个Java的应用程序,c3p0和下一个类: Dataobj.class表示对象类型:

    package c3p0pruebas.modelo;

import java.io.Serializable;

import java.sql.SQLData;
import java.sql.SQLException;
import java.sql.SQLInput;
import java.sql.SQLOutput;

public class Dataobj implements SQLData, Serializable {

    private String name;
    private Integer id;


    public Dataobj() {
    }

    public String getSQLTypeName() {
        return "DATAOBJ";
    }

    public void writeSQL(SQLOutput stream) throws SQLException {
        stream.writeInt(id.intValue());
        stream.writeString(name);
    }

    public void readSQL(SQLInput stream, String typeName) throws SQLException {
        id = new Integer(stream.readInt());
        name = stream.readString();
    }


    public void setName(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }
    ... and its gets and sets ....

主要类和主要方法:

Connection connection = DBConnectionManager.getInstance().getConnection("Mypool"); //I use a class to get connection
     CallableStatement cs = null;
     String error = "";
        try {
/*
//First I made a NativeExtractor of the connection, but the result is the same, I got it from Spring framework.            
//C3P0NativeJdbcExtractor extractor = new C3P0NativeJdbcExtractor();
            //OracleConnection newConnection = (OracleConnection) extractor.getNativeConnection(connection);

            //cs = (OracleCallableStatement) newConnection.prepareCall("{? = call F_IS_DATA_OBJECT(?)}");
*/
            //Creates the object
            Dataobj obj = new Dataobj();
            obj.setId(new Integer(33));
            obj.setName("myName");

            cs = connection.prepareCall("{? = call F_IS_DATA_OBJECT(?)}");

            cs.registerOutParameter(1, OracleTypes.VARCHAR);
            cs.setObject(2, obj);

            cs.execute();
            error = cs.getString(1);

            System.out.println("Result: " + error);

        } catch (SQLException e) {
            e.printStackTrace();
        } catch (Exception ex) {
            ex.printStackTrace();
        } finally {
            closeDBObjects(null,cs,null);
        }
     closeDBObjects(null, null, connection); //Close connection

执行得到:

Data object: id=33.

我无法获取String(Varchar2)值,即名称字符串。

对于对象类型的oracle数组,我遇到了同样的问题,它对JDBC很有用。当我使用Arrays时,它也没有字符串值:

//Here I use a NativeConnection ...
    Dataobj arrayOfData[] = new Dataobj[myDataObj.size()];
... //Makes the array of DataObj.
                ArrayDescriptor descriptor = ArrayDescriptor.createDescriptor("OBJ_ARRAY", newConnection);
            ARRAY arrayDatas = new ARRAY(descriptor, newConnection, arrayOfData);

//在此步骤中,arrayDatas的对象不是名称字符串...

感谢!!!

2 个答案:

答案 0 :(得分:0)

好的,它终于有效了。

搜索,我们找到了答案:

我们在数据库中更改数据定义,现在可以正常工作:

CREATE OR REPLACE
TYPE "DATAOBJ" AS OBJECT
(
  vid NUMBER,
  vname NCHAR(50)
)

谢谢!

答案 1 :(得分:0)

我遇到了同样的问题,我解决了没有更改VARCHAR2 to NCHAR,因为对我来说,NCHAR在Oracle中没有出现字符串,保持“?”在所有职位上。

我将WAR的oracle驱动程序更改为我的数据库版本,在我的例子中是11.2.0.1.0: http://www.oracle.com/technetwork/database/enterprise-edition/jdbc-112010-090769.html

我放了另一个驱动程序,即Oracle对象和集合的NLS: http://download.oracle.com/otn/utilities_drivers/jdbc/112/orai18n.jar

有了这个,我解决了问题,VARCHAR2工作正常。

祝你好运。