KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > ivata > groupware > container > persistence > hibernate > HibernateManager


1 /*
2  * Copyright (c) 2001 - 2005 ivata limited.
3  * All rights reserved.
4  * -----------------------------------------------------------------------------
5  * ivata groupware may be redistributed under the GNU General Public
6  * License as published by the Free Software Foundation;
7  * version 2 of the License.
8  *
9  * These programs are free software; you can redistribute them and/or
10  * modify them under the terms of the GNU General Public License
11  * as published by the Free Software Foundation; version 2 of the License.
12  *
13  * These programs are distributed in the hope that they will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
16  *
17  * See the GNU General Public License in the file LICENSE.txt for more
18  * details.
19  *
20  * If you would like a copy of the GNU General Public License write to
21  *
22  * Free Software Foundation, Inc.
23  * 59 Temple Place - Suite 330
24  * Boston, MA 02111-1307, USA.
25  *
26  *
27  * To arrange commercial support and licensing, contact ivata at
28  * http://www.ivata.com/contact.jsp
29  * -----------------------------------------------------------------------------
30  * $Log: HibernateManager.java,v $
31  * Revision 1.5 2005/04/29 02:48:15 colinmacleod
32  * Data bugfixes.
33  * Changed primary key back to Integer.
34  *
35  * Revision 1.4 2005/04/10 20:43:09 colinmacleod
36  * Added new themes.
37  * Changed id type to String.
38  * Changed i tag to em and b tag to strong.
39  * Improved PicoContainerFactory with NanoContainer scripts.
40  *
41  * Revision 1.3 2005/04/09 17:19:37 colinmacleod
42  * Changed copyright text to GPL v2 explicitly.
43  *
44  * Revision 1.2 2005/03/16 15:46:44 colinmacleod
45  * Added flush after save.
46  *
47  * Revision 1.1 2005/03/10 19:23:04 colinmacleod
48  * Moved to ivata groupware.
49  *
50  * Revision 1.5 2004/12/31 18:43:17 colinmacleod
51  * Added class checking of key (id) type for ivata masks.
52  *
53  * Revision 1.4 2004/11/12 15:57:10 colinmacleod
54  * Removed dependencies on SSLEXT.
55  * Moved Persistence classes to ivata masks.
56  *
57  * Revision 1.3 2004/09/30 15:15:55 colinmacleod
58  * Split off addressbook elements into security subproject.
59  *
60  * Revision 1.2 2004/08/01 11:55:02 colinmacleod
61  * Added removeAll.
62  *
63  * Revision 1.1 2004/07/13 19:42:44 colinmacleod
64  * Moved project to POJOs from EJBs.
65  * Applied PicoContainer to services layer (replacing session EJBs).
66  * Applied Hibernate to persistence layer (replacing entity EJBs).
67  * -----------------------------------------------------------------------------
68  */

69 package com.ivata.groupware.container.persistence.hibernate;
70
71 import org.apache.log4j.Logger;
72
73 import java.io.Serializable JavaDoc;
74 import java.util.Iterator JavaDoc;
75 import java.util.List JavaDoc;
76 import java.util.Map JavaDoc;
77 import java.util.Set JavaDoc;
78
79 import net.sf.hibernate.HibernateException;
80 import net.sf.hibernate.ObjectNotFoundException;
81 import net.sf.hibernate.Query;
82 import net.sf.hibernate.Session;
83 import net.sf.hibernate.SessionFactory;
84 import net.sf.hibernate.Transaction;
85
86 import com.ivata.groupware.container.persistence.QueryPersistenceManager;
87 import com.ivata.groupware.container.persistence.listener.AddPersistenceListener;
88 import com.ivata.groupware.container.persistence.listener.AmendPersistenceListener;
89 import com.ivata.groupware.container.persistence.listener.RemovePersistenceListener;
90 import com.ivata.mask.persistence.FinderException;
91 import com.ivata.mask.persistence.PersistenceException;
92 import com.ivata.mask.persistence.PersistenceSession;
93 import com.ivata.mask.persistence.right.PersistenceRights;
94 import com.ivata.mask.util.StringHandling;
95 import com.ivata.mask.valueobject.ValueObject;
96
97 /**
98  * <p>
99  * This class provides a persistence manager for the whole
100  * <strong>ivata groupware</strong> project. Every time a data object should be stored
101  * to or retrieved from the data store, it happens here.
102  * </p>
103  *
104  * @author Colin MacLeod
105  * <a HREF='mailto:colin.macleod@ivata.com'>colin.macleod@ivata.com</a>
106  * @since Mar 27, 2004
107  * @version $Revision: 1.5 $
108  */

109 public class HibernateManager implements QueryPersistenceManager, Serializable JavaDoc {
110     /**
111      * Logger for this class.
112      */

113     private static final Logger logger = Logger
114             .getLogger(HibernateManager.class);
115
116     /**
117      * Tells us what we can and can't do!
118      */

119     private PersistenceRights persistenceRights;
120     /**
121      * <p>
122      * This object is used to create the queries from strings and arguments.
123      * </p>
124      */

125     private HibernateQueryFactory queryFactory;
126     /**
127      * <p>
128      * Hibernate session factory.
129      * </p>
130      */

131     private SessionFactory sessionFactory;
132
133     /**
134      * <p>
135      * One and only constructor - called by Pico. Uses constructor arguments
136      * to initialize the whole object.
137      * </p>
138      *
139      * @param sessionFactoryParam Used to create <strong>Hibernate</strong> sessions!
140      * @param queryFactoryParam This object is used to create the queries from
141      * strings and arguments.
142      * @param interceptorParam
143      */

144     public HibernateManager(final SessionFactory sessionFactoryParam,
145             final HibernateQueryFactory queryFactoryParam,
146             final PersistenceRights persistenceRightsParam) {
147         this.sessionFactory = sessionFactoryParam;
148         this.queryFactory = queryFactoryParam;
149         this.persistenceRights = persistenceRightsParam;
150     }
151
152     /**
153      * <p>
154      * Add a new data object to the store.
155      * </p>
156      *
157      * @param session Open, valid persistence session used to store the object.
158      * @param valueObject Data object to be stored.
159      */

160     public ValueObject add(final PersistenceSession session,
161             final ValueObject valueObject) throws PersistenceException {
162         HibernateSession hibernateSession = (HibernateSession) session;
163         Session wrappedSession = hibernateSession.getSession();
164         Transaction wrappedTransaction = hibernateSession.getTransaction();
165
166         try {
167             wrappedSession.save(valueObject);
168             wrappedSession.flush();
169         } catch (Exception JavaDoc e) {
170             logger.error("Exception in add.", e);
171             try {
172                 wrappedTransaction.rollback();
173             } catch (HibernateException e2) {
174                 throw new PersistenceException("Error rolling back a transaction",
175                     e2);
176             }
177             throw new PersistenceException("Error saving a new instance of class '"
178                 + valueObject.getClass().getName()
179                 +"'",
180                 e);
181         }
182         return valueObject;
183     }
184     /**
185      * Refer to {@link }.
186      *
187      * @param dOClass
188      * @param listener
189      * @see com.ivata.groupware.container.persistence.QueryPersistenceManager#addAddListener(java.lang.Class, com.ivata.groupware.container.persistence.listener.AddPersistenceListener)
190      */

191     public void addAddListener(Class JavaDoc dOClass, AddPersistenceListener listener) {
192         HibernateInterceptor.addAddListener(dOClass, listener);
193     }
194
195
196     /**
197      * Refer to {@link }.
198      *
199      * @param dOClass
200      * @param listener
201      * @see com.ivata.groupware.container.persistence.QueryPersistenceManager#addAmendListener(java.lang.Class, com.ivata.groupware.container.persistence.listener.AddPersistenceListener)
202      */

203     public void addAmendListener(Class JavaDoc dOClass, AmendPersistenceListener listener) {
204         HibernateInterceptor.addAmendListener(dOClass, listener);
205     }
206
207
208     /**
209      * Refer to {@link }.
210      *
211      * @param dOClass
212      * @param listener
213      * @see com.ivata.groupware.container.persistence.QueryPersistenceManager#addRemoveListener(java.lang.Class, com.ivata.groupware.container.persistence.listener.AddPersistenceListener)
214      */

215     public void addRemoveListener(Class JavaDoc dOClass, RemovePersistenceListener listener) {
216         HibernateInterceptor.addRemoveListener(dOClass, listener);
217     }
218
219     /**
220      * <p>
221      * Change the values of a data object which already exists in the data
222      * store.
223      * </p>
224      *
225      * @param session Open, valid persistence session used to update the object.
226      * @param baseDO Data object to be modified.
227      */

228     public void amend(final PersistenceSession session,
229             final ValueObject baseDO) throws PersistenceException {
230         String JavaDoc className = baseDO.getClass().getName();
231         HibernateSession hibernateSession = (HibernateSession) session;
232         Session wrappedSession = hibernateSession.getSession();
233         Transaction wrappedTransaction = hibernateSession.getTransaction();
234
235         try {
236             wrappedSession.update(baseDO);
237         } catch (Exception JavaDoc e) {
238             logger.error("Exception in amend.", e);
239             try {
240                 wrappedTransaction.rollback();
241             } catch (HibernateException e2) {
242                 throw new PersistenceException("Error rolling back a transaction",
243                     e2);
244             }
245             throw new PersistenceException("Error updating an instance of class '"
246                 + baseDO.getClass().getName()
247                 +"' with id '"
248                 + baseDO.getIdString()
249                 + "'",
250                 e);
251         }
252     }
253
254     /**
255      * <p>
256      * Internal helper method. This one does all the hard work for retrieving
257      * objects or deleting multiple objects at once.
258      * </p>
259      *
260      * @param session Open, valid persistence session.
261      * @param queryName Name of the query within the query factory.
262      * @param queryArguments Arguments that apply to this query.
263      * @param pageSize If multiple rows should be returned, this indicates the
264      * maximum number to return. Set to <code>null</code> if a single instance
265      * should be returned, or if all instances are needed.
266      * @param pageNumber It is possible to select a subset of all matching rows
267      * by setting this parameter to a number greater than zero. This is used
268      * together with the <code>pageSize</code> argument. Set to
269      * <code>null</code> for a single result, or <code>0</code> to return the
270      * first page of results, or all results (with <code>pageNumber</code>
271      * <code>null</code>.).
272      * @param delete If <code>true</code>, all entries returned by this query
273      * will be deleted.
274      * @return
275      * @throws PersistenceException
276      */

277     private Object JavaDoc execute(final PersistenceSession session,
278             final String JavaDoc queryName,
279             final Object JavaDoc[] queryArguments,
280             final Integer JavaDoc pageSize,
281             final Integer JavaDoc pageNumber,
282             final boolean delete) throws PersistenceException {
283         HibernateSession hibernateSession = (HibernateSession) session;
284         Session wrappedSession = hibernateSession.getSession();
285
286         Object JavaDoc object = null;
287         HibernateQuery hibernateQuery = (HibernateQuery) queryFactory.generateQuery(queryName,
288             queryArguments);
289         Query q;
290         try {
291             q = wrappedSession.createQuery(hibernateQuery.getQueryString());
292             Map JavaDoc arguments = hibernateQuery.getArguments();
293             Set JavaDoc keys = arguments.keySet();
294             for (Iterator JavaDoc keyIterator = keys.iterator(); keyIterator.hasNext();) {
295                 String JavaDoc key = (String JavaDoc) keyIterator.next();
296                 Object JavaDoc value = arguments.get(key);
297                 q.setParameter(key, value);
298             }
299         } catch (HibernateException e) {
300             logger.error("Exception in execute.", e);
301             throw new PersistenceException("Error retrieving object "
302                 + "with query '"
303                 + hibernateQuery.getQueryString()
304                 + "', "
305                 + hibernateQuery.getArguments(),
306                 e);
307         }
308
309         // if delete was specified, or the page number was set, expect multiple
310
// results
311
if (delete
312                 || (pageNumber != null)) {
313             List JavaDoc results;
314             try {
315                 // if you specified a page size, limit the results
316
if ((pageSize != null)
317                         && (pageNumber != null)) {
318                     q.setMaxResults(pageSize.intValue());
319                     q.setFirstResult(pageSize.intValue() * pageNumber.intValue());
320                 }
321                 results = q.list();
322             } catch (HibernateException e) {
323                 throw new PersistenceException(queryName, e);
324             }
325             // if delete was specified, just discard the results
326
if (delete) {
327                 results.clear();
328                 results = null;
329             } else {
330                 object = results;
331             }
332
333         // otherwise we're trying to retrieve a single instance
334
} else {
335             try {
336                 object = q.uniqueResult();
337             } catch (HibernateException e) {
338                 throw new PersistenceException(queryName, e);
339             }
340             if (object == null) {
341                 throw new FinderException(queryName, queryArguments);
342             }
343         }
344         return object;
345     }
346
347     /**
348      * <p>
349      * Find all results which match the given query.
350      * </p>
351      *
352      * @param session Open, valid persistence session.
353      * @param queryName Name of the query within the query factory.
354      * @param queryArguments Arguments that apply to this query.
355      */

356     public List JavaDoc find(final PersistenceSession session,
357             final String JavaDoc queryName,
358             final Object JavaDoc[] queryArguments) throws PersistenceException {
359         return find(session, queryName, queryArguments, null, new Integer JavaDoc(0));
360     }
361
362
363     /**
364      * <p>
365      * Find all results which match the given query.
366      * </p>
367      *
368      * @param session Open, valid persistence session.
369      * @param queryName Name of the query within the query factory.
370      * @param queryArguments Arguments that apply to this query.
371      * @param pageSize This indicates the maximum number of results to return.
372      * Set to <code>null</code> if all instances are needed.
373      * @param pageNumber It is possible to select a subset of all matching rows
374      * by setting this parameter to a number greater than zero. This is used
375      * together with the <code>pageSize</code> argument. Set to
376      * <code>0</code> to return the
377      * first page of results, or all results (with <code>pageNumber</code>
378      * <code>null</code>.).
379      */

380     public List JavaDoc find(final PersistenceSession session,
381             final String JavaDoc queryName,
382             final Object JavaDoc[] queryArguments,
383             final Integer JavaDoc pageSize,
384             final Integer JavaDoc pageNumber) throws PersistenceException {
385         return (List JavaDoc) execute(session, queryName, queryArguments, pageSize,
386                 pageNumber, false);
387     }
388
389
390     /**
391      * <p>
392      * Find all results which have the given class.
393      * </p>
394      *
395      * @param session Open, valid persistence session.
396      * @param dOClass Class of the data objects to return.
397      */

398     public List JavaDoc findAll(final PersistenceSession session,
399             final Class JavaDoc dOClass) throws PersistenceException {
400         HibernateSession hibernateSession = (HibernateSession) session;
401         Session wrappedSession = hibernateSession.getSession();
402
403         List JavaDoc results = null;
404         try {
405             results = wrappedSession.find("from "
406                 + dOClass.getName());
407         } catch (HibernateException e) {
408             logger.error("Exception in findAll.", e);
409             throw new PersistenceException("Error retrieving all objects from "
410                 + dOClass.getName(),
411                 e);
412         }
413         return results;
414     }
415
416     /**
417      * <p>
418      * Find a single result given the class and unique identifier.
419      * </p>
420      *
421      * @param session Open, valid persistence session.
422      * @param dOClass Class of the data object to return.
423      * @param key Unique identifier of the data object to return.
424      */

425     public ValueObject findByPrimaryKey(final PersistenceSession session,
426             final Class JavaDoc dOClass,
427             final Serializable JavaDoc key) throws PersistenceException {
428         HibernateSession hibernateSession = (HibernateSession) session;
429         Session wrappedSession = hibernateSession.getSession();
430
431         if (key == null) {
432             throw new PersistenceException(dOClass.getName()
433                 + ": key is null");
434         }
435
436         ValueObject baseDO = null;
437         Transaction transaction;
438         try {
439             // TODO: at the moment, everything is indexed as an string - this
440
// probably needs to be abstracted somehow
441
Integer JavaDoc id = StringHandling.integerValue(key.toString());
442             baseDO = (ValueObject) wrappedSession.load(dOClass, id);
443         } catch (ObjectNotFoundException e) {
444             throw new FinderException(dOClass, key, e);
445         } catch (HibernateException e) {
446             logger.error("Exception in findByPrimaryKey.", e);
447             throw new PersistenceException(e);
448         }
449         if (baseDO == null) {
450             throw new FinderException(dOClass, key, null);
451         }
452         return baseDO;
453     }
454
455
456     /**
457      * <p>
458      * Find a single result which matches the given query.
459      * </p>
460      *
461      * @param session Open, valid persistence session.
462      * @param queryName Name of the query within the query factory.
463      * @param queryArguments Arguments that apply to this query.
464      */

465     public ValueObject findInstance(final PersistenceSession session,
466             final String JavaDoc queryName,
467             final Object JavaDoc[] queryArguments) throws PersistenceException {
468         return (ValueObject) execute(session, queryName, queryArguments, null, null, false);
469     }
470
471     /**
472      * <p>
473      * Find a single integer result which matches the given query.
474      * </p>
475      *
476      * @param session Open, valid persistence session.
477      * @param queryName Name of the query within the query factory.
478      * @param queryArguments Arguments that apply to this query.
479      */

480     public Integer JavaDoc findInteger(final PersistenceSession session,
481             final String JavaDoc queryName,
482             final Object JavaDoc[] queryArguments) throws PersistenceException {
483         return (Integer JavaDoc) execute(session, queryName, queryArguments, null, null, false);
484     }
485
486
487     /**
488      * <p>
489      * Find a single string result which matches the given query.
490      * </p>
491      *
492      * @param session Open, valid persistence session.
493      * @param queryName Name of the query within the query factory.
494      * @param queryArguments Arguments that apply to this query.
495      */

496     public String JavaDoc findString(final PersistenceSession session,
497             final String JavaDoc queryName,
498             final Object JavaDoc[] queryArguments) throws PersistenceException {
499         return (String JavaDoc) execute(session, queryName, queryArguments, null, null, false);
500     }
501     /**
502      * Tells us what we can and can't do!
503      *
504      * @return Returns the persistence rights.
505      */

506     public PersistenceRights getPersistenceRights() {
507         return persistenceRights;
508     }
509
510
511     /**
512      * Refer to {@link }.
513      *
514      * @return
515      * @throws PersistenceException
516      * @see com.ivata.mask.persistence.PersistenceManager#openSession()
517      */

518     public PersistenceSession openSession() throws PersistenceException {
519         return openSession(null);
520     }
521
522
523     /**
524      * <p>
525      * Open a new persistence session.
526      * </p>
527      *
528      * @return New session which can be used in future queries.
529      */

530     public PersistenceSession openSession(Object JavaDoc systemSession)
531             throws PersistenceException {
532         try {
533             HibernateInterceptor interceptor = new HibernateInterceptor(this,
534                     sessionFactory);
535             Session session = sessionFactory.openSession(interceptor);
536             HibernateSession hibernateSession = new HibernateSession(session,
537                     session.beginTransaction(),
538                     systemSession);
539             interceptor.setHibernateSession(hibernateSession);
540             return hibernateSession;
541         } catch (HibernateException e) {
542             logger.error("Exception in openSession.", e);
543             throw new PersistenceException("Error creating a new hibernate session.",
544                 e);
545         }
546     }
547
548     /**
549      * <p>
550      * Remove a single object from the data store.
551      * </p>
552      *
553      * @param session Open, valid persistence session.
554      * @param dOClass Class of the data object to remove.
555      * @param key Unique identifier of the data object to remove.
556      */

557     public void remove(final PersistenceSession session,
558             final Class JavaDoc dOClass,
559             final Serializable JavaDoc key) throws PersistenceException {
560         HibernateSession hibernateSession = (HibernateSession) session;
561         Session wrappedSession = hibernateSession.getSession();
562         Transaction wrappedTransaction = hibernateSession.getTransaction();
563         try {
564             wrappedSession.delete("from "
565                 + dOClass.getName()
566                 + " dO where dO.id = "
567                 + key);
568         } catch (Exception JavaDoc e) {
569             logger.error("Exception in remove.", e);
570             try {
571                 wrappedTransaction.rollback();
572             } catch (HibernateException e2) {
573                 throw new PersistenceException("Error rolling back a transaction",
574                     e2);
575             }
576             throw new PersistenceException("Error removing an instance of class '"
577                 + dOClass.getName()
578                 +"' with id '"
579                 + key
580                 + "'",
581                 e);
582         }
583     }
584
585     /**
586      * <p>
587      * Remove a single object from the data store.
588      * </p>
589      *
590      * @param session Open, valid persistence session.
591      * @param baseDO Data object to be removed.
592      */

593     public void remove(final PersistenceSession session,
594             final ValueObject valueObject) throws PersistenceException {
595         remove(session, valueObject.getClass(), valueObject.getIdString());
596     }
597
598     /**
599      * Refer to {@link QueryPersistenceManager#removeAll}.
600      *
601      * @param session Refer to {@link QueryPersistenceManager#removeAll}.
602      * @param queryName Refer to {@link QueryPersistenceManager#removeAll}.
603      * @param queryArguments Refer to {@link QueryPersistenceManager#removeAll}.
604      * @throws PersistenceException
605      * Refer to {@link QueryPersistenceManager#removeAll}.
606      * TODO: this doesn't notify listeners!!
607      */

608     public void removeAll(final PersistenceSession session,
609             final String JavaDoc queryName,
610             final Object JavaDoc[] queryArguments) throws PersistenceException {
611         execute(session, queryName, queryArguments, null, null, true);
612     }
613 }
614
Popular Tags