Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

java.lang.ClassCastException: oracle.sql.TIMESTAMP cannot be cast to java.sql.Timestamp

Tags:

oracle

jdbc

I am working on an application that streams ResultSet over a network. I ended up using a CachedRowSetImpl class. But when I connect to an Oracle DB, I get an error like this

java.lang.ClassCastException: oracle.sql.TIMESTAMP cannot be cast to java.sql.Timestamp

Please help.

The source code is as follows:

ResultSet res = response.getResultSet(); //resultset from the server
while (res.next()) {
    Agent agent = new Agent();
    agent.setName(res.getString(2));
    agent.setMobile(res.getString(1));
    agent.setBalance(res.getLong(4));
    agent.setLastUpdate(res.getDate(3)); //date from the result set
    agent.setAccountNumber(res.getString(5));
}

The error ...

java.lang.ClassCastException: oracle.sql.TIMESTAMP cannot be cast to java.sql.Timestamp java.lang.ClassCastException: oracle.sql.TIMESTAMP cannot be cast to java.sql.Timestamp at com.sun.rowset.CachedRowSetImpl.getDate(CachedRowSetImpl.java:2139)

like image 922
Adeniran Opeyemi Avatar asked Nov 07 '12 12:11

Adeniran Opeyemi


5 Answers

The javadoc for ResultSet.getObject() mandates that the JDBC type should be mapped to a Java type as prescribed by the JDBC spec (TIMESTAMP -> java.sqlTimestmp):

This method will return the value of the given column as a Java object. The type of the Java object will be the default Java object type corresponding to the column's SQL type, following the mapping for built-in types specified in the JDBC specification.

As you have noticed, the Oracle driver is by default not compliant with the standard and uses oracle.sql.TIMESTAMP instead (which does not extend java.sql.Timestamp). The good news is that you can force JDBC compliance by setting the oracle.jdbc.J2EE13Compliant system property to true during vm startup:

java -Doracle.jdbc.J2EE13Compliant=true YourApplication

or programmatically

System.getProperties().setProperty("oracle.jdbc.J2EE13Compliant", "true")

Once you do this, getResult() will return instances of java.sql.Timestamp, as expected.

For more details see the relevant section from the Oracle JDBC Driver Documentation, which describes several ways of setting oracle.jdbc.J2EE13Compliant.

like image 112
Bogdan Calmac Avatar answered Nov 15 '22 19:11

Bogdan Calmac


I found a way out.

 oracle.sql.TIMESTAMP ts = (oracle.sql.TIMESTAMP) res.getObject("last_update");
 agent.setLastUpdate(new Date(ts.dateValue().getTime()));
like image 42
Adeniran Opeyemi Avatar answered Nov 15 '22 21:11

Adeniran Opeyemi


Add this this line to the JVM setting. It will work.

-Doracle.jdbc.J2EE13Compliant=true
like image 35
Amir Amiri Avatar answered Nov 15 '22 21:11

Amir Amiri


This is because oracle.sql.TIMESTAMP is not derived from java.sql.TIMESTAMP:

java.lang.Object
  -> oracle.sql.Datum
     -> oracle.sql.TIMESTAMP

You can't cast the former into the later.

Instead use oracle.sql.TIMESTAMP.timestampValue():

public Timestamp timestampValue(Calendar cal) throws SQLException

Calls toTimestamp to convert internal Oracle Date and Calendar to a Java Timestamp.

like image 34
Vincent Malgrat Avatar answered Nov 15 '22 20:11

Vincent Malgrat


This can be solved by using the timestampValue() function present in the oracle.sql.TIMESTAMP class. This method will convert oracle.sql.TIMESTAMP into java.sql.Timestamp.

oracle.sql.TIMESTAMP ts = (oracle.sql.TIMESTAMP) res.getObject("last_update"); agent.setLastUpdate(ts.timestampValue());

like image 1
Sam ツ Avatar answered Nov 15 '22 19:11

Sam ツ