oracle jdbc driver 18c
java.lang.ClassCastException: oracle.sql.TIMESTAMP no se puede convertir a java.sql.Timestamp (7)
Estoy trabajando en una aplicación que transmite ResultSet a través de una red. Terminé usando una clase CachedRowSetImpl. Pero cuando me conecto a una base de datos Oracle, me sale un error como este
java.lang.ClassCastException: oracle.sql.TIMESTAMP no se puede convertir a java.sql.Timestamp
Por favor ayuda.
El código fuente es el siguiente:
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));
}
El error ...
java.lang.ClassCastException: oracle.sql.TIMESTAMP no se puede convertir a java.sql.Timestamp java.lang.ClassCastException: oracle.sql.TIMESTAMP no se puede convertir a java.sql.Timestamp en com.sun.rowset.CachedRowSetImplique (CachedRowSetImpl.java:2139)
Agregue esta línea a la configuración de JVM. Funcionará.
-Doracle.jdbc.J2EE13Compliant=true
Creo que el problema es que su setLastUpdate
está esperando un objeto de tipo java.sql.Date
.
Ahora, cuando usa agent.setLastUpdate(res.getDate(3));
El res.getDate(3)
debe devolver un objeto que su método no espera para que pueda haber una ClassCastException
para eso.
Pruebe este código y vea si soluciona su problema o no:
agent.setLastUpdate(new java.util.Date(res.getDate(3).getTime()));
El javadoc para ResultSet.getObject() ordena que el tipo JDBC se debe asignar a un tipo de Java según lo prescrito por la especificación JDBC (TIMESTAMP -> java.sqlTimestmp):
Este método devolverá el valor de la columna dada como un objeto Java. El tipo de objeto Java será el tipo de objeto Java predeterminado correspondiente al tipo de SQL de la columna, siguiendo la asignación para los tipos incorporados especificados en la especificación JDBC.
Como ha notado, el controlador de Oracle no es compatible con el estándar de manera predeterminada y utiliza oracle.sql.TIMESTAMP
en oracle.sql.TIMESTAMP
lugar (que no extiende java.sql.Timestamp
). La buena noticia es que puede forzar el cumplimiento de JDBC configurando la propiedad del sistema oracle.jdbc.J2EE13Compliant como true
durante el inicio de vm:
java -Doracle.jdbc.J2EE13Compliant=true YourApplication
o programáticamente
System.getProperties().setProperty("oracle.jdbc.J2EE13Compliant", "true")
Una vez que haga esto, getResult () devolverá instancias de java.sql.Timestamp
, como se esperaba.
Para obtener más detalles, consulte la sección correspondiente de la documentación del controlador JDBC de Oracle , que describe varias formas de configurar oracle.jdbc.J2EE13Compliant.
Encontré una salida.
oracle.sql.TIMESTAMP ts = (oracle.sql.TIMESTAMP) res.getObject("last_update");
agent.setLastUpdate(new Date(ts.dateValue().getTime()));
Esto se debe a que oracle.sql.TIMESTAMP
no se deriva de java.sql.TIMESTAMP
:
java.lang.Object -> oracle.sql.Datum -> oracle.sql.TIMESTAMP
No puedes echar lo primero en lo posterior.
En su lugar, use oracle.sql.TIMESTAMP.timestampValue()
:
public Timestamp timestampValue(Calendar cal) throws SQLException
Llama a
Timestamp
para convertir laDate
y el calendario internos de Oracle en unaTimestamp
Java.
Esto se puede resolver utilizando la función timestampValue () presente en la clase oracle.sql.TIMESTAMP. Este método convertirá oracle.sql.TIMESTAMP en java.sql.Timestamp.
oracle.sql.TIMESTAMP ts = (oracle.sql.TIMESTAMP) res.getObject ("last_update"); agent.setLastUpdate (ts.timestampValue ());
Lo más probable es que haya utilizado getTIMESTAMP()
lugar de getTimestamp()
. Los métodos getTIMESTAMP()
(y getDATE()
son extensiones en OracleResultSet
que devuelven tipos específicos de Oracle.
Si no, entonces no estás utilizando un controlador JDBC, porque el tipo de retorno de getDate()
es java.sql.Date
y de getTimestamp()
es java.sql.Timestamp
, por lo que no puede ser un tipo totalmente diferente como en tu pregunta .