原因:java.lang.ClassCastException:无法将java.sql.Timestamp强制转换为java.sql.Date

Naa*_*aaN 3 java classcastexception cachedrowset

对于以下代码段,出现以下给定错误:

  try {
        cRows = new CachedRowSetImpl();
        while(cRows.next()) 
        {
        MyClass myClass = new MyClass();
        myClass.setPrevDate(cRows.getDate("PREV_DATE")); // In debug mode, the error was throwing when I press Resume from here.
        }
      }
Run Code Online (Sandbox Code Playgroud)

错误:

Caused by: java.lang.ClassCastException: java.sql.Timestamp cannot be cast to java.sql.Date
Run Code Online (Sandbox Code Playgroud)

在数据库中,该列的数据类型DATE仅为。我不知道这里要到哪里Timestamp

Joo*_*gen 5

已淘汰:

使用java.util.Date该字段。 java.sql.Timestamp是它的直接子类。由于是java.sql.Date-这条时间的一部分。为什么Java数据库驱动程序将DATE用作时间戳记有点奇怪。什么是数据库供应商?您指定长度了吗?确实只存储日期吗?


研究:

我查看了CachedRowSetImpl.java,并使用了Oracle的文档和Oracle可以很好地完成所有工作(java.sql.Date,java.sql.Time,java.sql.Timestamp可转换)。CachedRowSetImpl确实只是将DATE的对象(并且getObject可能会随时间返回高分辨率的Timestamp-带时间)转换为java.sql.Date,这是错误的。因此,请覆盖替代此太阳的等级。

      /*
       * The object coming back from the db could be
       * a date, a timestamp, or a char field variety.
       * If it's a date type return it, a timestamp
       * we turn into a long and then into a date,
       * char strings we try to parse. Yuck.
       */
       switch (RowSetMD.getColumnType(columnIndex)) {
           case java.sql.Types.DATE: {
               long sec = ((java.sql.Date)value).getTime();
               return new java.sql.Date(sec);
       }
Run Code Online (Sandbox Code Playgroud)


Naa*_*aaN 5

我对此问题进行了研究,并找到了一些有用的链接。我发现DATE和TIMESTAMP之间的混淆是特定于JDBC驱动程序的。并且大多数链接建议使用-Doracle.jdbc.V8Compatible=true。对于我的JBoss,我已经设置好了run.bat,问题解决了。

  1. https://community.oracle.com/thread/68918?start=0&tstart=0

  2. http://www.coderanch.com/t/90891/JBoss/oracle-jdbc-Compatible-true

  3. https://community.oracle.com/message/3613155

oracle doc共享不同的解决方案:

  • 更改表以使用TIMESTAMP而不是DATE。这可能极少发生,但在可能的情况下是最佳解决方案。

  • 更改您的应用程序以使用defineColumnType将列定义为TIMESTAMP而不是DATE。之所以存在问题,是因为除非您真的不想使用defineColumnType,否则(请参阅什么是defineColumnType以及何时应使用它?)。

  • 更改您的应用程序以使用getTimestamp而不是getObject。如果可能的话,这是一个很好的解决方案,但是许多应用程序都包含依赖于getObject的通用代码,因此并不总是可能的。

  • 设置V8Compatible连接属性。这告诉JDBC驱动程序使用旧的映射而不是新的映射。您可以将此标志设置为连接属性或系统属性。您可以通过将连接属性添加到传递给DriverManager.getConnection的java.util.Properties对象或OracleDataSource.setConnectionProperties中来设置连接属性。您可以通过在Java命令行中包含-D选项来设置系统属性。

    java -Doracle.jdbc.V8Compatible =“ true” MyApp

这是链接:http : //www.oracle.com/technetwork/database/enterprise-edition/jdbc-faq-090281.html#08_00