我收到以下代码片段的以下给定错误:
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
来自哪里。
答案 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
中设置了这个问题,问题得到了解决。
http://www.coderanch.com/t/90891/JBoss/oracle-jdbc-Compatible-true
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