Jonalca
Jonalca

Reputation: 576

SQLData reading mapped objects with an interface

Introduction

I am creating an interface read from mapped objects on a OracleSQL database. So far so good, I successfully created the TYPEs and TABLEs but when reading them with the java.sql.SQLData it's giving me this casting error.

Code

public class EmpresaSqlData extends Empresa implements SQLData {

    private String sql_type = "USER.EMPRESA";

    public EmpresaSqlData() {}

    public EmpresaSqlData(String cif, String nom, Contacte contacte) {
        super(cif, nom, contacte);
    }    

    public EmpresaSqlData(String cif, String nom) {
        super(cif, nom);
    }

    @Override
    public String getSQLTypeName() throws SQLException {
        return sql_type;
    }

    @Override
    public void readSQL(SQLInput stream, String typeName) throws SQLException {
        sql_type = typeName;
        setNom(stream.readString());
        setCif(stream.readNString());//Write the object
        setContacte(stream.readObject(new Contacte)); //Fix??
    }

    @Override
    public void writeSQL(SQLOutput stream) throws SQLException {
        stream.writeString(getNom());
        stream.writeString(getCif());
        stream.writeObject(new ContacteSqlData());        
    }    
}

The above is need afterwards when I execute queries such as:

@Override
    public List<EmpresaSqlData> findAll() {
        EmpresaSqlData empresaSqlDataSQLData;
        List<EmpresaSqlData> corpList = new ArrayList<>();
        String query = "SELECT VALUE (e) FROM empreses e";

       try (Connection conn = cf.getConnection();
             PreparedStatement statement 
                    = conn.prepareStatement(query);){

            //Initial connection setup
            conn.setTypeMap(map);

            ResultSet rs = statement.executeQuery();


            while (rs.next()){      
                System.out.println(rs.getObject(1, EmpresaSqlData.class)); //Error here "Type of column not valid"
            }            

            return corpList;              

        } catch (SQLException e) {
            Logger.getLogger(EmpresaDAOImpl.class.getName()).log(Level.SEVERE, null, e);
            return null;
        }
    }

Research

From the docs at "Implementing readSQL() and writeSQL() Methods" (Ctrl+C and Ctrl+F + Enter to get to the point) it states that:

· The readSQL() method takes as input a SQLInput stream and a string that indicates the SQL type name of the data (in other words, the name of the Oracle object type, such as EMPLOYEE)

Problem

Then I have tried to read the SQLobject returned by readSQL() and cast it to the Java object Contacte

setContacte((Contacte)stream.readObject());

which gives me this Exception:

Exception in thread "main" java.lang.ClassCastException: oracle.sql.STRUCT cannot be cast to activitat3.logica.Contacte
    at activitat3.logica.EmpresaSqlData.readSQL(EmpresaSqlData.java:44)
    at oracle.sql.STRUCT.toClass(STRUCT.java:662)
    at oracle.sql.STRUCT.toJdbc(STRUCT.java:599)
    at oracle.jdbc.driver.NamedTypeAccessor.getObject(NamedTypeAccessor.java:140)
    at oracle.jdbc.driver.NamedTypeAccessor.getObject(NamedTypeAccessor.java:110)
    at oracle.jdbc.driver.GeneratedStatement.getObject(GeneratedStatement.java:261)
    at oracle.jdbc.driver.GeneratedScrollableResultSet.getObject(GeneratedScrollableResultSet.java:761)
    at activitat3.dades.impl.EmpresaDAOImpl.findAll(EmpresaDAOImpl.java:184)
    at activitat3.test.Main.llistarEmpreses(Main.java:330)
    at activitat3.test.Main.main(Main.java:93)

This Exception states that an object read with the readSQL() method from java.sql.SQLData can not be casted to a Java object.

How I am supposed to work with an Object this way?

readInt() returns Integer, readString returns String, but readObject() can not be casted or given a custom Object?

Goal

I want to read a mapped object from an OracleSQL database this way.

Upvotes: 0

Views: 656

Answers (1)

Luke Woodward
Luke Woodward

Reputation: 65054

From the comments, it seems the problem was that a similar mapping for the Contacte class was missing or incomplete.

The stacktrace shows that the EmpresaSqlData class is being entered, so the mapping for this type is working. If the Contacte class is not being mapped from the database, then there is presumably no such mapping of an Oracle type either directly to this class, or, as suggested by your EmpresaSqlData, to a subclass of it.

Upvotes: 1

Related Questions