-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 5 posts ] 
Author Message
 Post subject: UserType for TIMESTAMP WITH TIME ZONE field in Oracle
PostPosted: Sat Apr 02, 2005 7:08 am 
Newbie

Joined: Sat Apr 02, 2005 6:55 am
Posts: 3
Hi.
I need to create an hibernate UserType to map to TIMESTAMP WITH TIME ZONE field in oracle..

in my nullSafeGet(Resultset rs, ........)
method I am trying to retrieve the Timestamp with time zone information..

if I do rs.getDate(....) I get Timestamp but I lose timezone...

if I do rs.getString(...) I retrieve Timestamp and TimeZone information as a string which looks like '2004-8-8 9.0.0.123457000 US/Eastern'.. I want to know how this format is determined? Can it be manipulated? Can I make sure whether it will change if I change my JDBC driver etc..?

Do you have any suggestions how to retrieve TIMESTAMP WITH TIME ZONE field in my UserType?

Thanks


Top
 Profile  
 
 Post subject:
PostPosted: Mon Apr 04, 2005 8:24 am 
Newbie

Joined: Sat Apr 02, 2005 6:55 am
Posts: 3
I think this is a common problem, can anybody help me with UserType for TIMESTAMP WITH TIME ZONE field?


Top
 Profile  
 
 Post subject:
PostPosted: Tue Apr 05, 2005 10:01 am 
Newbie

Joined: Sat Apr 02, 2005 6:55 am
Posts: 3
any ideas?


Top
 Profile  
 
 Post subject: Saving timezone with timestamp
PostPosted: Mon May 02, 2005 11:39 am 
Beginner
Beginner

Joined: Fri Feb 11, 2005 2:40 pm
Posts: 27
We need to preserve the timezone too. I read a article saying you can map it to a custom type that you write on your own, but it sounds that it should be something built into Hibernate. Anybody knows if HB 3.0 has better support for it?


Top
 Profile  
 
 Post subject:
PostPosted: Mon May 02, 2005 2:12 pm 
Newbie

Joined: Mon Jan 31, 2005 1:33 pm
Posts: 11
You will have to create a custom type to handle this situation. There are two approaches you can take.
1) Use the oracle.sql.TIMESTAMPTZ type for reading to and from the prepared statement. This has one major drawback, the TIMESTAMPTZ construction initiates a socket connection to the database to retrieve database settings.
2) Use string values to read and write to the database. This has one minor drawback, the format of the string can be modified on the database side via settings. As long as you know the settings this is probably the prefered way. We developed this approach and here is our code....

Code:
import java.io.Serializable;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.Date;
import java.util.Calendar;

import org.hibernate.HibernateException;
import org.hibernate.usertype.UserType;

import oracle.jdbc.OracleTypes;

public class TimestampWithTimeZoneType implements UserType, Serializable
{
    private static final int[]  SQL_TYPES = {OracleTypes.TIMESTAMPTZ};

    public int[] sqlTypes()
    {
        return SQL_TYPES;
    }

    public Class returnedClass()
    {
        return Calendar.class;
    }

    public boolean equals(Object x, Object y) throws HibernateException
    {
        if ( x == y ) return true;
        if ( x == null || y == null) return false;
       
        return x.equals(y);
    }

    public int hashCode(Object x) throws HibernateException
    {
        return x.hashCode();
    }

    public Object nullSafeGet(ResultSet rs, String[] names, Object owner) throws HibernateException, SQLException
    {
        String tzString = rs.getString(names[0]);
       
        // transform TimestampWithTZ to a Timestamp object
        Calendar cal = StringUtil.getCalendar(tzString);
        return cal;
    }

    public void nullSafeSet(PreparedStatement stmt, Object value, int index) throws HibernateException, SQLException
    {
        String tsString = StringUtil.getTimestampTZString((Calendar) value);
        stmt.setString(index,tsString);
    }

    public Object deepCopy(Object value) throws HibernateException
    {
        return value;
    }

    public boolean isMutable()
    {
        return true;
    }

    public Serializable disassemble(Object value) throws HibernateException
    {
        return (Serializable) value;
    }

    public Object assemble(Serializable cached, Object owner) throws HibernateException
    {
        return cached;
    }

    public Object replace(Object original, Object target, Object owner) throws HibernateException
    {
        return original;
    }
   
}


Also, here is the associated StringUtil functions which expect the default setting for the timestamp with timezone string format.
Code:
    public static String getTimestampTZString(Calendar cal)
    {
        StringBuilder sb = new StringBuilder();
        sb.append(cal.get(Calendar.DAY_OF_MONTH));
        sb.append(DASH);
        sb.append(months[cal.get(Calendar.MONTH)]);
        sb.append(DASH);
        String year = Integer.toString(cal.get(Calendar.YEAR)).substring(2);
        sb.append(year);
        sb.append(" ");
        sb.append(cal.get(Calendar.HOUR));
        sb.append(COLON);
        sb.append(cal.get(Calendar.MINUTE));
        sb.append(COLON);
        sb.append(cal.get(Calendar.SECOND));
        sb.append(".");
      int millis = cal.get(Calendar.MILLISECOND);
      if (millis < 100) sb.append('0');
      if (millis < 10) sb.append('0');
        sb.append(millis);
        sb.append(ampm[cal.get(Calendar.AM_PM)]);
        sb.append(" ");
        sb.append(cal.getTimeZone().getID());
       
        return sb.toString();
    }

    public static Calendar getCalendar(String in)
    {
        Calendar cal = Calendar.getInstance();
        String[] tokens = in.split("\\s");
        cal.setTimeZone(TimeZone.getTimeZone(tokens[2]));
        StringTokenizer st = new StringTokenizer(tokens[0],"-");
        cal.set(Calendar.YEAR,Integer.valueOf(st.nextToken()));
        cal.set(Calendar.MONTH,Integer.valueOf(st.nextToken()) - 1);
        cal.set(Calendar.DAY_OF_MONTH,Integer.valueOf(st.nextToken()));
       
        st = new StringTokenizer(tokens[1],".");
        cal.set(Calendar.HOUR_OF_DAY,Integer.valueOf(st.nextToken()));
        cal.set(Calendar.MINUTE,Integer.valueOf(st.nextToken()));
        cal.set(Calendar.SECOND,Integer.valueOf(st.nextToken()));
        //get only millis, Calendar doesn't deal with nano seconds
        cal.set(Calendar.MILLISECOND,Integer.valueOf(st.nextToken().substring(0,3)));
       
        return cal;
    }


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 5 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.