These two days, I was working on getting timezone information from oracle using Hibernate. The version of Hibernate is 3.2.4. I found that the return value always returned a Calendar with the tomcat server’s timezone when we were getting a Calendar field.
My environment: a column with data type as “TIMESTAMP WITH TIME ZONE DEFAULT SYSTIMESTAMP” (Oracle 10g). You can find my another article about TIMESTAMP/Date in oracle.
Firstly, Google ~ It told me that there was a bug about this in Hibernate 2.*.
“Calendar loses time zone information
Affects Version/s: 2.1.3
Fix Version/s: 3.0 alpha
http://opensource.atlassian.com/projects/hibernate/browse/HB-1006″
But this bug is just for saving a Calender with timezone. It has been fixed in Hibernate 3.*.
So I traced the hibernate source code:
public Object get(ResultSet rs, String name) throws HibernateException, SQLException {
Timestamp ts = rs.getTimestamp(name);
if (ts!=null) {
Calendar cal = new GregorianCalendar();
if ( Environment.jvmHasTimestampBug() ) {
cal.setTime( new Date( ts.getTime() + ts.getNanos() / 1000000 ) );
}
else {
cal.setTime(ts);
}
return cal;
}
else {
return null;
}
}
public void set(PreparedStatement st, Object value, int index) throws HibernateException, SQLException {
final Calendar cal = (Calendar) value;
//st.setTimestamp( index, new Timestamp( cal.getTimeInMillis() ), cal ); //JDK 1.5 only
st.setTimestamp( index, new Timestamp( cal.getTime().getTime() ), cal );
}
I think CalendarType.get() doesn’t assemble the Calendar with the timezone. So we store the date with GMT timezone and convert it to other timezone when getting it out.