View Javadoc
1   /*
2    *  Copyright 2001-2012 Stephen Colebourne
3    *
4    *  Licensed under the Apache License, Version 2.0 (the "License");
5    *  you may not use this file except in compliance with the License.
6    *  You may obtain a copy of the License at
7    *
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    *
10   *  Unless required by applicable law or agreed to in writing, software
11   *  distributed under the License is distributed on an "AS IS" BASIS,
12   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   *  See the License for the specific language governing permissions and
14   *  limitations under the License.
15   */
16  package org.joda.time.contrib.hibernate;
17  
18  import java.io.Serializable;
19  import java.sql.PreparedStatement;
20  import java.sql.ResultSet;
21  import java.sql.SQLException;
22  import java.sql.Timestamp;
23  
24  import org.hibernate.HibernateException;
25  import org.hibernate.engine.SessionImplementor;
26  import org.hibernate.type.StandardBasicTypes;
27  import org.hibernate.type.Type;
28  import org.hibernate.usertype.CompositeUserType;
29  import org.joda.time.DateTime;
30  import org.joda.time.Interval;
31  
32  /**
33   * Persist {@link org.joda.time.Interval} via hibernate. Internally, this class
34   * collaborates with {@link org.joda.time.contrib.hibernate.PersistentDateTime}
35   * to convert the start and end components of an Interval to and from the
36   * database correspondents. This class allows clients to execute hibernate or
37   * JPA queries using the attribute names "start" and "end." For example,
38   * <blockquote>
39   * "from Foo where :date is between barInterval.start and barInterval.end"
40   * </blockquote>
41   * 
42   * @author Christopher R. Gardner (chris_gardner76@yahoo.com)
43   */
44  public class PersistentInterval implements CompositeUserType, Serializable {
45  
46      private static final String[] PROPERTY_NAMES = new String[] { "start", "end" };
47  
48      private static final Type[] TYPES = new Type[] { StandardBasicTypes.TIMESTAMP, StandardBasicTypes.TIMESTAMP };
49  
50      public Object assemble(Serializable cached, SessionImplementor session, Object owner) throws HibernateException {
51          return cached;
52      }
53  
54      public Object deepCopy(Object value) throws HibernateException {
55          return value;
56      }
57  
58      public Serializable disassemble(Object value, SessionImplementor session) throws HibernateException {
59          return (Serializable) value;
60      }
61  
62      public boolean equals(Object x, Object y) throws HibernateException {
63          if (x == y) {
64              return true;
65          }
66          if (x == null || y == null) {
67              return false;
68          }
69          return x.equals(y);
70      }
71  
72      public String[] getPropertyNames() {
73          return PROPERTY_NAMES;
74      }
75  
76      public Type[] getPropertyTypes() {
77          return TYPES;
78      }
79  
80      public Object getPropertyValue(Object component, int property) throws HibernateException {
81          Interval interval = (Interval) component;
82          return (property == 0) ? interval.getStart().toDate() : interval.getEnd().toDate();
83      }
84  
85      public int hashCode(Object x) throws HibernateException {
86          return x.hashCode();
87      }
88  
89      public boolean isMutable() {
90          return false;
91      }
92  
93      public Object nullSafeGet(ResultSet resultSet, String[] names, SessionImplementor session, Object owner)
94              throws HibernateException, SQLException {
95          if (resultSet == null) {
96              return null;
97          }
98          PersistentDateTime pst = new PersistentDateTime();
99          DateTime start = (DateTime) pst.nullSafeGet(resultSet, names[0]);
100         DateTime end = (DateTime) pst.nullSafeGet(resultSet, names[1]);
101         if (start == null || end == null) {
102             return null;
103         }
104         return new Interval(start, end);
105     }
106 
107     public void nullSafeSet(PreparedStatement statement, Object value, int index, SessionImplementor session)
108             throws HibernateException, SQLException {
109         if (value == null) {
110             statement.setNull(index, StandardBasicTypes.TIMESTAMP.sqlType());
111             statement.setNull(index + 1, StandardBasicTypes.TIMESTAMP.sqlType());
112             return;
113         }
114         Interval interval = (Interval) value;
115         statement.setTimestamp(index, asTimeStamp(interval.getStart()));
116         statement.setTimestamp(index + 1, asTimeStamp(interval.getEnd()));
117     }
118 
119     private Timestamp asTimeStamp(DateTime time) {
120         return new Timestamp(time.getMillis());
121     }
122 
123     public Object replace(Object original, Object target, SessionImplementor session, Object owner)
124             throws HibernateException {
125         return original;
126     }
127 
128     public Class returnedClass() {
129         return Interval.class;
130     }
131 
132     public void setPropertyValue(Object component, int property, Object value) throws HibernateException {
133         throw new UnsupportedOperationException("Immutable Interval");
134     }
135 
136 }