引起:java.lang.ClassCastException:java.sql.Timestamp无法强制转换为java.sql.Date

时间:2014-09-17 13:47:46

标签: 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.
        }
      }

错误:

Caused by: java.lang.ClassCastException: java.sql.Timestamp cannot be cast to java.sql.Date

在数据库中,该列的数据类型仅为DATE。我无法弄清楚Timestamp来自哪里。

2 个答案:

答案 0 :(得分:5)

<强> 过时:

对字段使用java.util.Date java.sql.Timestamp是其直接子类。与java.sql.Date一样 - 剥离时间部分。为什么java数据库驱动程序将DATE设为Timestamp有点奇怪。什么是数据库供应商?你指定了一个长度吗?确实只存储了日期吗?


<强> 研究之:

我查看了CachedRowSetImpl.java,Oracle的文档和Oracle做得很好(java.sql.Date,java.sql.Time,java.sql.Timestamp convertible)。 CachedRowSetImpl只是简单地转换DATE的对象(并且getObject可能会将高分辨率时间戳 - 随时间返回)返回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);
       }

答案 1 :(得分: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
  4. oracle doc分享不同的解决方案:

    • 更改表格以使用TIMESTAMP而不是DATE。这可能是 很少可能,但它是最好的解决方案。

    • 更改应用程序以使用defineColumnType定义列 作为TIMESTAMP而不是DATE。这有问题,因为 你真的不想使用defineColumnType,除非你必须(见 什么是defineColumnType以及何时应该使用它? )。

    • 将应用程序改为使用getTimestamp而不是getObject。这个 在可能的情况下是一个很好的解决方案,但许多应用程 依赖于getObject的通用代码,因此它始终不可能。

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

      java -Doracle.jdbc.V8Compatible =&#34; true&#34; MyApp的

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