--最終解決:將VO中所有 @Temporal(TemporalType.DATE)全部替換爲 @Temporal(TemporalType.TIMESTAMP)
【現象】
近期某功能需要將一整個VO轉化成JSON串,報出以下錯誤
2012-4-12 11:35:58 org.apache.catalina.core.StandardWrapperValve invoke
嚴重: Servlet.service() for servlet default threw exception
java.lang.IllegalArgumentException
at java.sql.Date.getHours(Unknown Source)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.apache.commons.beanutils.PropertyUtilsBean.invokeMethod(PropertyUtilsBean.java:2170)
at org.apache.commons.beanutils.PropertyUtilsBean.getSimpleProperty(PropertyUtilsBean.java:1332)
at org.apache.commons.beanutils.PropertyUtilsBean.getNestedProperty(PropertyUtilsBean.java:770)
at org.apache.commons.beanutils.PropertyUtilsBean.getProperty(PropertyUtilsBean.java:846)
at org.apache.commons.beanutils.PropertyUtils.getProperty(PropertyUtils.java:426)
at net.sf.json.JSONObject.fromBean(JSONObject.java:199)
【初步研究】
1.此VO中某日期字段實際上是java.util.Date類型的;
2.又看了一下java.sql.Date extends java.util.Date 中的 getHours方法
/**
* This method is deprecated and should not be used because SQL Date
* values do not have a time component.
*
* @deprecated
* @exception java.lang.IllegalArgumentException if this method is invoked
* @see #setHours
*/
public int getHours() {
throw new java.lang.IllegalArgumentException();
}
3.上網查,Hibernate jpa註釋@Temporal(TemporalType.DATE)會將此列映射爲java.sql.Date
/**
* Type used to indicate a specific mapping of <code>java.util.Date</code>
* or <code>java.util.Calendar</code>.
*
* @since Java Persistence 1.0
*/
public enum TemporalType {
/**
* Map as <code>java.sql.Date</code>
*/
DATE,
/**
* Map as <code>java.sql.Time</code>
*/
TIME,
/**
* Map as <code>java.sql.Timestamp</code>
*/
TIMESTAMP
}
【中間彎路】
重寫java.sql.Date ,把裏面的會throw new java.lang.IllegalArgumentException();的set、get方法全部幹掉——以前經常無奈重寫底層包中的類,重寫JDK裏的類還是第一次幹,結果也就第一次發現:這次並沒像以往一樣會優先選用自己重寫的類,CLASSPATH=./;%CLASSPATH%也不行;(--求達人解釋原因@_@)
【最終解決】
將@Temporal(TemporalType.DATE)全部替換爲@Temporal(TemporalType.TIMESTAMP),這樣屬性是一個java.sql.TimeStamp型,它可沒有重寫getHours方法。另外考慮數據庫是Informix,本來Date型就沒時分秒的(非time),原VO中原始類型定義又是java.util.Date,因此初步認爲沒啥不良影響。(個人認爲,即使是Oracle的Date,應該也是無影響的,如果year-to-day的,不用的它的時分秒就好了)。
目前實際應用中暫未發現不良反應。