Thursday, February 9, 2012 2:46

Hibernate lost timezone when getting timestamp from Oracle

Tagged with: , ,
Posted by on Wednesday, November 12, 2008, 16:11
This news item was posted in Team Fight category and has 0 Comments so far.

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.

Leave a Reply

You can leave a response, or trackback from your own site.