1   package org.wcb.model.dao.impl;
2   
3   
4   import org.hibernate.criterion.DetachedCriteria;
5   import org.hibernate.criterion.Order;
6   import org.hibernate.criterion.Restrictions;
7   import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
8   import org.springframework.dao.DataAccessException;
9   import org.wcb.exception.DAOException;
10  import org.wcb.model.dao.IDao;
11  
12  import java.util.List;
13  import java.util.Collection;
14  import java.util.logging.Logger;
15  
16  /**
17   * <small>
18   * Copyright (c)  2006  wbogaardt.
19   * Permission is granted to copy, distribute and/or modify this document
20   * under the terms of the GNU Free Documentation License, Version 1.2
21   * or any later version published by the Free Software Foundation;
22   * with no Invariant Sections, no Front-Cover Texts, and no Back-Cover
23   * Texts.  A copy of the license is included in the section entitled "GNU
24   * Free Documentation License".
25   * <p/>
26   * $File:  $ <br>
27   * $Change:  $ submitted by $Author: wbogaardt $ at $DateTime: Jan 26, 2006 10:38:53 AM $ <br>
28   * </small>
29   *
30   * @author wbogaardt
31   * @version 1
32   * Date: Jan 26, 2006
33   * Time: 10:38:53 AM
34   */
35  
36  public class AbstractHibernateDAO extends HibernateDaoSupport implements IDao {
37  
38      /**
39       * The logging utility object
40       */
41      protected final Logger LOG = Logger.getLogger(AbstractHibernateDAO.class.getName());
42      private Class objectClass;
43  
44      /**
45       * Constructor that establishes the class that will be used for DB operations
46       * when the class is not passed explicitly as one of the method signatures.
47       * @param clazz the class
48       */
49      protected AbstractHibernateDAO(Class clazz) {
50          this.objectClass = clazz;
51      }
52  
53      /**
54       * Empty constructor.
55       */
56      public AbstractHibernateDAO() {
57          // Do nothing
58      }
59  
60      /**
61       * This uses the hibernate template to save or update an object into
62       * the database.
63       * @param o object to save using save or update 
64       */
65      public void saveOrUpdateObject( Object o ) {
66          getHibernateTemplate().saveOrUpdate( o );
67      }
68  
69      /**
70       * Only saves the object to a database.
71       * @param o object to save to the database.
72       */
73      public void saveObject( Object o ) {
74          getHibernateTemplate().save( o );
75      }
76  
77      public Collection saveOrUpdateAllObjects(Collection coll) {
78          getHibernateTemplate().saveOrUpdateAll(coll);
79          return coll;
80      }
81  
82      /**
83       * Retrieve an Object given the id and the class
84       * specified during construction.
85       * @param id the identifier
86       * @return the retrieved object
87       * @throws DAOException which wraps the root exception
88       */
89      protected Object getObject(Integer id) throws DAOException {
90          return getObject(this.objectClass, id);
91      }
92  
93      /**
94       * Retrieve an Object given the id.
95       * @param clazz the class to lookup
96       * @param id the identifier
97       * @return the retrieved object
98       * @throws DAOException which wraps the root exception
99       */
100     protected Object getObject(Class clazz, Integer id) throws DAOException {
101         try {
102             return getHibernateTemplate().get(clazz, id);
103         } catch (DataAccessException e) {
104             throw new DAOException(e);
105         }
106     }
107 
108     /**
109      * Retrieve an Object given the id and the class
110      * specified during construction.
111      * @param id the identifier
112      * @return the retrieved object
113      * @throws DAOException which wraps the root exception
114      */
115     protected Object getObject(Long id) throws DAOException {
116         return getObject(this.objectClass, id);
117     }
118 
119     /**
120      * Retrieve an Object given the id.
121      * @param clazz the class to lookup
122      * @param id the identifier
123      * @return the retrieved object
124      * @throws DAOException which wraps the root exception
125      */
126     protected Object getObject(Class clazz, Long id) throws DAOException {
127         try {
128             return getHibernateTemplate().get(clazz, id);
129         } catch (DataAccessException e) {
130             throw new DAOException(e);
131         }
132     }
133 
134 
135     /**
136      * Gets a list of active Objects of the class
137      * specified during construction.
138      * The query is cached in hibernate query cache.
139      * @return a populated list of objects
140      * @throws DAOException which wraps the root exception
141      */
142     protected List getObjects() throws DAOException {
143         return getObjects(this.objectClass);
144     }
145 
146     /**
147      * Gets a list of active Object of the given classname.
148      * The query is cached in hibernate query cache.
149      * @param clazz The class to lookup
150      * @return a populated list of objects
151      * @throws DAOException which wraps the root exception
152      */
153     protected List getObjects(Class clazz) throws DAOException {
154         try {
155             boolean b = getHibernateTemplate().isCacheQueries();
156             getHibernateTemplate().setCacheQueries(true);
157             List objects = getHibernateTemplate().loadAll(clazz);
158             getHibernateTemplate().setCacheQueries(b);
159             return objects;
160         } catch (DataAccessException e) {
161             throw new DAOException(e);
162         }
163     }
164 
165     /**
166      * Gets a list of objects, filtered by a properties that match
167      * the given values.  The objects will be of the type of the class
168      * that was established during construction.
169      * <p/>
170      * For example, to find all the phone numbers with a 310 area code
171      * and 998 prefix:<br/>
172      * <code>
173      * getObjectsBy(PhoneNumberBO.class, new String[]{"areaCode", "prefix"}, new Object[]{"310", "998"})
174      * </code>
175      * <p/>
176      * Note that <code>toString()</code> will be called on the given value.
177      * @param properties the names of the object properties to be considered
178      * @param values the values that the object properties must match
179      * @param orderByProperties properties used to affect the result set order
180      * @return list of matching objects
181      * @throws DAOException which wraps the root exception
182      */
183     public List getObjectsBy(String[] properties, Object[] values, String[] orderByProperties)
184             throws DAOException {
185         return getObjectsBy(this.objectClass, properties, values, orderByProperties);
186     }
187 
188     /**
189      * Gets a list of objects, filtered by a properties that match
190      * the given values.
191      * <p/>
192      * For example, to find all the phone numbers with a 310 area code
193      * and 998 prefix:<br/>
194      * <code>
195      * getObjectsBy(PhoneNumberBO.class, new String[]{"areaCode", "prefix"}, new Object[]{"310", "998"})
196      * </code>
197      * <p/>
198      * Note that <code>toString()</code> will be called on the given value.
199      * @param clazz the class representing the type of objects held in the list
200      * @param properties the names of the object properties to be considered
201      * @param values the values that the object properties must match
202      * @param orderByProperties properties used to affect the result set order
203      * @return list of matching objects
204      * @throws DAOException which wraps the root exception
205      */
206     public List getObjectsBy(Class clazz, String[] properties, Object[] values, String[] orderByProperties)
207             throws DAOException {
208         DetachedCriteria criteria = DetachedCriteria.forClass(clazz);
209         if (properties != null && properties.length > 0) {
210             for (int i = 0; i < properties.length; i++) {
211                 criteria.add(Restrictions.eq(properties[i], values[i]));
212             }
213         }
214         if (orderByProperties != null && orderByProperties.length > 0) {
215             for(int i = 0; i < orderByProperties.length; i++) {
216                 criteria.addOrder(Order.desc(orderByProperties[i]));
217             }
218         }
219         return getHibernateTemplate().findByCriteria(criteria);
220     }
221 
222     /**
223      * Gets a list of objects, filtered by a property that matches
224      * the given value.  The objects will be of the type of the class
225      * that was established during construction.
226      * <p/>
227      * For example, to find all the phone numbers with a 310 area code:<br/>
228      * <code>getObjectsBy(PhoneNumberBO.class, "areaCode", "310")</code>
229      * <p/>
230      * Note that <code>toString()</code> will be called on the given value.
231      * @param property the name of the object property to be considered
232      * @param value the value that the object property must match
233      * @return list of matching objects
234      * @throws DAOException which wraps the root exception
235      */
236     public List getObjectsBy(String property, Object value) throws DAOException {
237         return getObjectsBy(this.objectClass, property, value);
238     }
239 
240     /**
241      * Gets a list of objects, filtered by a property that matches
242      * the given value.
243      * <p/>
244      * For example, to find all the phone numbers with a 310 area code:<br/>
245      * <code>getObjectsBy(PhoneNumberBO.class, "areaCode", "310")</code>
246      * <p/>
247      * Note that <code>toString()</code> will be called on the given value.
248      * @param clazz the class representing the type of objects held in the list
249      * @param property the name of the object property to be considered
250      * @param value the value that the object property must match
251      * @return list of matching objects
252      * @throws DAOException which wraps the root exception
253      */
254     public List getObjectsBy(Class clazz, String property, Object value) throws DAOException {
255         return this.getObjectsBy(clazz, new String[] {property}, new Object[] {value}, null);
256     }
257 
258     /**
259      * Gets a list of objects, filtered by properties that match
260      * the given values.  The objects will be of the type of the class
261      * that was established during construction.
262      * <p/>
263      * For example, to find all the phone numbers with a 310 area code
264      * and 998 prefix:<br/>
265      * <code>getObjectsBy(PhoneNumberBO.class, "areaCode", "310", "prefix", "998")</code>
266      * <p/>
267      * Note that <code>toString()</code> will be called on the given values.
268      * @param property1 the name of the 1st object property to be considered
269      * @param value1 the value that the 1st object property must match
270      * @param property2 the name of the 2nd object property to be considered
271      * @param value2 the value that the 2nd object property must match
272      * @return list of matching objects
273      * @throws DAOException which wraps the root exception
274      */
275     protected List getObjectsBy(String property1, Object value1, String property2, Object value2)
276             throws DAOException {
277         return this.getObjectsBy(this.objectClass, property1, value1, property2, value2);
278     }
279 
280     /**
281      * Gets a list of objects, filtered by properties that match
282      * the given values.
283      * <p/>
284      * For example, to find all the phone numbers with a 310 area code
285      * and 998 prefix:<br/>
286      * <code>getObjectsBy(PhoneNumberBO.class, "areaCode", "310", "prefix", "998")</code>
287      * <p/>
288      * Note that <code>toString()</code> will be called on the given values.
289      * @param clazz the class representing the type of objects held in the list
290      * @param property1 the name of the 1st object property to be considered
291      * @param value1 the value that the 1st object property must match
292      * @param property2 the name of the 2nd object property to be considered
293      * @param value2 the value that the 2nd object property must match
294      * @return list of matching objects
295      * @throws DAOException which wraps the root exception
296      */
297     protected List getObjectsBy(Class clazz, String property1, Object value1, String property2, Object value2)
298             throws DAOException {
299         return this.getObjectsBy(clazz, new String[] {property1, property2}, new Object[] {value1, value2}, null);
300     }
301 }