001    /*
002     *  Copyright 2001-2011 Stephen Colebourne
003     *
004     *  Licensed under the Apache License, Version 2.0 (the "License");
005     *  you may not use this file except in compliance with the License.
006     *  You may obtain a copy of the License at
007     *
008     *      http://www.apache.org/licenses/LICENSE-2.0
009     *
010     *  Unless required by applicable law or agreed to in writing, software
011     *  distributed under the License is distributed on an "AS IS" BASIS,
012     *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013     *  See the License for the specific language governing permissions and
014     *  limitations under the License.
015     */
016    package org.joda.time.contrib.hibernate;
017    
018    import java.io.Serializable;
019    import java.sql.PreparedStatement;
020    import java.sql.ResultSet;
021    import java.sql.SQLException;
022    import java.sql.Types;
023    
024    import org.hibernate.HibernateException;
025    import org.hibernate.type.StandardBasicTypes;
026    import org.hibernate.usertype.UserType;
027    import org.joda.time.DateTime;
028    import org.joda.time.DateTimeZone;
029    
030    /**
031     * Persist {@link org.joda.time.DateTime} via hibernate. The timezone will be
032     * stored in an extra column.
033     * 
034     * @author Mario Ivankovits (mario@ops.co.at)
035     */
036    public class PersistentDateTimeTZ implements UserType, Serializable {
037    
038        public static final PersistentDateTimeTZ INSTANCE = new PersistentDateTimeTZ();
039    
040        private static final int[] SQL_TYPES = new int[] { Types.TIMESTAMP, Types.VARCHAR, };
041    
042        public int[] sqlTypes() {
043            return SQL_TYPES;
044        }
045    
046        public Class returnedClass() {
047            return DateTime.class;
048        }
049    
050        public boolean equals(Object x, Object y) throws HibernateException {
051            if (x == y) {
052                return true;
053            }
054            if (x == null || y == null) {
055                return false;
056            }
057            DateTime dtx = (DateTime) x;
058            DateTime dty = (DateTime) y;
059            return dtx.equals(dty);
060        }
061    
062        public int hashCode(Object object) throws HibernateException {
063            return object.hashCode();
064        }
065    
066        public Object nullSafeGet(ResultSet resultSet, String[] strings, Object object) throws HibernateException, SQLException {
067            Object timestamp = StandardBasicTypes.TIMESTAMP.nullSafeGet(resultSet, strings[0]);
068            Object timezone = StandardBasicTypes.STRING.nullSafeGet(resultSet, strings[1]);
069            if (timestamp == null || timezone == null) {
070                return null;
071            }
072            return new DateTime(timestamp, DateTimeZone.forID(timezone.toString()));
073        }
074    
075        public void nullSafeSet(PreparedStatement preparedStatement, Object value, int index) throws HibernateException, SQLException {
076            if (value == null) {
077                StandardBasicTypes.TIMESTAMP.nullSafeSet(preparedStatement, null, index);
078                StandardBasicTypes.STRING.nullSafeSet(preparedStatement, null, index + 1);
079            } else {
080                DateTime dt = (DateTime) value;
081                StandardBasicTypes.TIMESTAMP.nullSafeSet(preparedStatement, dt.toDate(), index);
082                StandardBasicTypes.STRING.nullSafeSet(preparedStatement, dt.getZone().getID(), index + 1);
083            }
084        }
085    
086        public Object deepCopy(Object value) throws HibernateException {
087            return value;
088        }
089    
090        public boolean isMutable() {
091            return false;
092        }
093    
094        public Serializable disassemble(Object value) throws HibernateException {
095            return (Serializable) value;
096        }
097    
098        public Object assemble(Serializable cached, Object value) throws HibernateException {
099            return cached;
100        }
101    
102        public Object replace(Object original, Object target, Object owner) throws HibernateException {
103            return original;
104        }
105    
106    }