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

Nidheesh picture Nidheesh · Sep 17, 2014 · Viewed 40.2k times · Source

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.

Answer

Joop Eggen picture Joop Eggen · Sep 17, 2014

Obsolete:

Use java.util.Date for the field. java.sql.Timestamp is a direct subclass of it. As is java.sql.Date - that strips the time part. Why the java database driver takes DATE to be Timestamp is a bit weird. What is the database vendor? Did you specify a length or so? Are indeed only dates stored?


Researched:

I looked into CachedRowSetImpl.java, and Oracle's docs and Oracle does everything fine (java.sql.Date, java.sql.Time, java.sql.Timestamp convertible). The CachedRowSetImpl does simply cast the DATE's Object (and getObject is likely to return the high resolution Timestamp - with time) to java.sql.Date, and that's wrong. So override or substitute this sun's class.

      /*
       * 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);
       }