3

I am getting the below given error for the following code snippets:

  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.
        }
      }

Error:

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

In the database, the datatype for the column is DATE only. I am not able to figure out where the Timestamp is coming here.

4

2 回答 2

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 或 OracleDataSource.setConnectionProperties 的 java.util.Properties 对象来设置连接属性。通过在 java 命令行中包含 -D 选项来设置系统属性。

    java -Doracle.jdbc.V8Compatible="true" MyApp

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

于 2014-09-18T14:27:02.523 回答
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 可转换)。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);
       }
于 2014-09-17T14:28:45.023 回答