001    /*****************************************************************************
002     * Copyright (c) PicoContainer Organization. All rights reserved.            *
003     * ------------------------------------------------------------------------- *
004     * The software in this package is published under the terms of the BSD      *
005     * style license a copy of which has been included with this distribution in *
006     * the license.html file.                                                    *
007     *                                                                           *
008     * Idea by Rachel Davies, Original code by Aslak Hellesoy and Paul Hammant   *
009     *****************************************************************************/
010    package org.nanocontainer.persistence.hibernate;
011    
012    import java.io.Serializable;
013    import java.sql.Connection;
014    
015    import org.hibernate.CacheMode;
016    import org.hibernate.Criteria;
017    import org.hibernate.EntityMode;
018    import org.hibernate.Filter;
019    import org.hibernate.FlushMode;
020    import org.hibernate.HibernateException;
021    import org.hibernate.Interceptor;
022    import org.hibernate.LockMode;
023    import org.hibernate.Query;
024    import org.hibernate.ReplicationMode;
025    import org.hibernate.SQLQuery;
026    import org.hibernate.Session;
027    import org.hibernate.SessionFactory;
028    import org.hibernate.Transaction;
029    import org.hibernate.stat.SessionStatistics;
030    import org.nanocontainer.persistence.ExceptionHandler;
031    import org.picocontainer.Startable;
032    
033    /**
034     * Session component with failover behaviour in case of hibernate exception. Old session is disposed
035     * and new one is obtained transparently. Session creation is done lazily.
036     * 
037     * @author Jose Peleteiro <juzepeleteiro@intelli.biz>
038     * @version $Id: SessionComponent.java 2510 2005-09-22 10:11:19Z mauro $
039     */
040    public class SessionComponent implements Session, Startable {
041    
042        private Session session = null;
043        
044            private SessionFactory sessionFactory;
045        private Interceptor interceptor;
046        protected ExceptionHandler hibernateExceptionHandler;
047    
048            public SessionComponent(final SessionFactory sessionFactory) {
049            this.sessionFactory = sessionFactory;
050                    hibernateExceptionHandler = new PingPongExceptionHandler();
051                    interceptor = null;
052            }
053    
054            public SessionComponent(final SessionFactory sessionFactory, final ExceptionHandler hibernateExceptionHandler) {
055            this.sessionFactory = sessionFactory;
056                    this.hibernateExceptionHandler = hibernateExceptionHandler;
057                    interceptor = null;
058            }
059    
060            public SessionComponent(final SessionFactory sessionFactory, final Interceptor interceptor) {
061            this.sessionFactory = sessionFactory;
062                    hibernateExceptionHandler = new PingPongExceptionHandler();
063                    this.interceptor = interceptor;
064            }
065    
066            public SessionComponent(final SessionFactory sessionFactory, final ExceptionHandler hibernateExceptionHandler, final Interceptor interceptor) {
067            this.sessionFactory = sessionFactory;
068                    this.hibernateExceptionHandler = hibernateExceptionHandler;
069                    this.interceptor = interceptor;
070            }
071    
072            /**
073             * Obtain hibernate session.  
074             */
075            protected final Session getDelegatedSession(boolean create) {
076            if (create && (session == null)) {
077                try {
078                    session = interceptor == null ? sessionFactory.openSession() : sessionFactory.openSession(interceptor);
079                } catch (RuntimeException ex) {
080                    throw handleException(ex);
081                }
082            }
083    
084            return session;
085            }
086    
087            /**
088             * Calls getDelegatedSession(true)
089             */
090            protected final Session getDelegatedSession() {
091            return getDelegatedSession(true);
092            }
093    
094            /**
095             * Perform actions to dispose "burned" session properly.
096             */
097            protected void invalidateDelegatedSession() throws HibernateException {
098            if (session != null) {
099                try {
100                    session.clear();
101                    session.close();
102                } catch (HibernateException ex) {
103                    throw handleException(ex);
104                } finally {
105                    session = null;
106                }
107            }
108            }
109    
110            /**
111             * Invalidates the session calling {@link #invalidateDelegatedSession()} and convert the <code>cause</code> using
112             * a {@link ExceptionHandler} if it's available otherwise just return the <code>cause</code> back.
113             */
114            protected RuntimeException handleException(RuntimeException cause) throws HibernateException {
115                    try {
116                            invalidateDelegatedSession();
117                    } catch (RuntimeException e) {
118                            // Do nothing, only the original exception should be reported.
119                    }
120    
121                    return hibernateExceptionHandler.handle(cause);
122            }
123    
124            /**
125             * org.picocontainer.Startable.start()
126             */
127            public void start() {
128                    // do nothing
129            }
130    
131            /**
132             * org.picocontainer.Startable.stop()
133             */
134            public void stop() {
135                    close();
136            }
137    
138            public Transaction beginTransaction() throws HibernateException {
139                    try {
140                            return getDelegatedSession().beginTransaction();
141                    } catch (RuntimeException ex) {
142                            throw handleException(ex);
143                    }
144            }
145    
146            public void cancelQuery() throws HibernateException {
147                    try {
148                            getDelegatedSession().cancelQuery();
149                    } catch (RuntimeException ex) {
150                            throw handleException(ex);
151                    }
152            }
153    
154            public void clear() {
155                    try {
156                            if (session == null) {
157                                    return;
158                            }
159    
160                            session.clear();
161                    } catch (RuntimeException ex) {
162                            throw handleException(ex);
163                    }
164            }
165    
166            public Connection close() throws HibernateException {
167                    try {
168                            if (session == null) {
169                                    // See Hibernate's javadoc. Returns Connection only when it only was gave by application.
170                                    return null;
171                            }
172    
173                            return session.close();
174                    } catch (RuntimeException ex) {
175                            throw handleException(ex);
176                    }
177            }
178    
179            public Connection connection() throws HibernateException {
180                    try {
181                            return getDelegatedSession().connection();
182                    } catch (RuntimeException ex) {
183                            throw handleException(ex);
184                    }
185            }
186    
187            public boolean contains(Object object) {
188                    try {
189                            return getDelegatedSession().contains(object);
190                    } catch (RuntimeException ex) {
191                            throw handleException(ex);
192                    }
193            }
194    
195            public Criteria createCriteria(Class persistentClass) {
196                    try {
197                            return getDelegatedSession().createCriteria(persistentClass);
198                    } catch (RuntimeException ex) {
199                            throw handleException(ex);
200                    }
201            }
202    
203            public Criteria createCriteria(Class persistentClass, String alias) {
204                    try {
205                            return getDelegatedSession().createCriteria(persistentClass, alias);
206                    } catch (RuntimeException ex) {
207                            throw handleException(ex);
208                    }
209            }
210    
211            public Criteria createCriteria(String entityName) {
212                    try {
213                            return getDelegatedSession().createCriteria(entityName);
214                    } catch (RuntimeException ex) {
215                            throw handleException(ex);
216                    }
217            }
218    
219            public Criteria createCriteria(String entityName, String alias) {
220                    try {
221                            return getDelegatedSession().createCriteria(entityName, alias);
222                    } catch (RuntimeException ex) {
223                            throw handleException(ex);
224                    }
225            }
226    
227            public Query createFilter(Object collection, String queryString) throws HibernateException {
228                    try {
229                            return getDelegatedSession().createFilter(collection, queryString);
230                    } catch (RuntimeException ex) {
231                            throw handleException(ex);
232                    }
233            }
234    
235            public Query createQuery(String queryString) throws HibernateException {
236                    try {
237                            return getDelegatedSession().createQuery(queryString);
238                    } catch (RuntimeException ex) {
239                            throw handleException(ex);
240                    }
241            }
242    
243            public SQLQuery createSQLQuery(String queryString) throws HibernateException {
244                    try {
245                            return getDelegatedSession().createSQLQuery(queryString);
246                    } catch (RuntimeException ex) {
247                            throw handleException(ex);
248                    }
249            }
250    
251            public void delete(Object object) throws HibernateException {
252                    try {
253                            getDelegatedSession().delete(object);
254                    } catch (RuntimeException ex) {
255                            throw handleException(ex);
256                    }
257            }
258    
259            public void disableFilter(String filterName) {
260                    try {
261                            getDelegatedSession().disableFilter(filterName);
262                    } catch (RuntimeException ex) {
263                            throw handleException(ex);
264                    }
265            }
266    
267            public Connection disconnect() throws HibernateException {
268                    try {
269                            return getDelegatedSession().disconnect();
270                    } catch (RuntimeException ex) {
271                            throw handleException(ex);
272                    }
273            }
274    
275            public Filter enableFilter(String filterName) {
276                    try {
277                            return getDelegatedSession().enableFilter(filterName);
278                    } catch (RuntimeException ex) {
279                            throw handleException(ex);
280                    }
281            }
282    
283            public void evict(Object object) throws HibernateException {
284                    try {
285                            getDelegatedSession().evict(object);
286                    } catch (RuntimeException ex) {
287                            throw handleException(ex);
288                    }
289            }
290    
291            public void flush() throws HibernateException {
292                    try {
293                            if (session == null) {
294                                    return;
295                            }
296    
297                            session.flush();
298                    } catch (RuntimeException ex) {
299                            throw handleException(ex);
300                    }
301            }
302    
303            public Object get(Class clazz, Serializable id) throws HibernateException {
304                    try {
305                            return getDelegatedSession().get(clazz, id);
306                    } catch (RuntimeException ex) {
307                            throw handleException(ex);
308                    }
309            }
310    
311            public Object get(Class clazz, Serializable id, LockMode lockMode) throws HibernateException {
312                    try {
313                            return getDelegatedSession().get(clazz, id, lockMode);
314                    } catch (RuntimeException ex) {
315                            throw handleException(ex);
316                    }
317            }
318    
319            public Object get(String entityName, Serializable id) throws HibernateException {
320                    try {
321                            return getDelegatedSession().get(entityName, id);
322                    } catch (RuntimeException ex) {
323                            throw handleException(ex);
324                    }
325            }
326    
327            public Object get(String entityName, Serializable id, LockMode lockMode) throws HibernateException {
328                    try {
329                            return getDelegatedSession().get(entityName, id, lockMode);
330                    } catch (RuntimeException ex) {
331                            throw handleException(ex);
332                    }
333            }
334    
335            public CacheMode getCacheMode() {
336                    try {
337                            return getDelegatedSession().getCacheMode();
338                    } catch (RuntimeException ex) {
339                            throw handleException(ex);
340                    }
341            }
342    
343            public LockMode getCurrentLockMode(Object object) throws HibernateException {
344                    try {
345                            return getDelegatedSession().getCurrentLockMode(object);
346                    } catch (RuntimeException ex) {
347                            throw handleException(ex);
348                    }
349            }
350    
351            public Filter getEnabledFilter(String filterName) {
352                    try {
353                            return getDelegatedSession().getEnabledFilter(filterName);
354                    } catch (RuntimeException ex) {
355                            throw handleException(ex);
356                    }
357            }
358    
359            public EntityMode getEntityMode() {
360                    try {
361                            return getDelegatedSession().getEntityMode();
362                    } catch (RuntimeException ex) {
363                            throw handleException(ex);
364                    }
365            }
366    
367            public String getEntityName(Object object) throws HibernateException {
368                    try {
369                            return getDelegatedSession().getEntityName(object);
370                    } catch (RuntimeException ex) {
371                            throw handleException(ex);
372                    }
373            }
374    
375            public FlushMode getFlushMode() {
376                    try {
377                            return getDelegatedSession().getFlushMode();
378                    } catch (RuntimeException ex) {
379                            throw handleException(ex);
380                    }
381            }
382    
383            public Serializable getIdentifier(Object object) throws HibernateException {
384                    try {
385                            return getDelegatedSession().getIdentifier(object);
386                    } catch (RuntimeException ex) {
387                            throw handleException(ex);
388                    }
389            }
390    
391            public Query getNamedQuery(String queryName) throws HibernateException {
392                    try {
393                            return getDelegatedSession().getNamedQuery(queryName);
394                    } catch (RuntimeException ex) {
395                            throw handleException(ex);
396                    }
397            }
398    
399            public Session getSession(EntityMode entityMode) {
400                    try {
401                            return getDelegatedSession().getSession(entityMode);
402                    } catch (RuntimeException ex) {
403                            throw handleException(ex);
404                    }
405            }
406    
407            public SessionFactory getSessionFactory() {
408                    try {
409                            return getDelegatedSession().getSessionFactory();
410                    } catch (RuntimeException ex) {
411                            throw handleException(ex);
412                    }
413            }
414    
415            public SessionStatistics getStatistics() {
416                    try {
417                            return getDelegatedSession().getStatistics();
418                    } catch (RuntimeException ex) {
419                            throw handleException(ex);
420                    }
421            }
422    
423            public boolean isConnected() {
424                    try {
425                            return getDelegatedSession().isConnected();
426                    } catch (RuntimeException ex) {
427                            throw handleException(ex);
428                    }
429            }
430    
431            public boolean isDirty() throws HibernateException {
432                    try {
433                            return getDelegatedSession().isDirty();
434                    } catch (RuntimeException ex) {
435                            throw handleException(ex);
436                    }
437            }
438    
439            public boolean isOpen() {
440                    try {
441                            return getDelegatedSession().isOpen();
442                    } catch (RuntimeException ex) {
443                            throw handleException(ex);
444                    }
445            }
446    
447            public Object load(Class theClass, Serializable id) throws HibernateException {
448                    try {
449                            return getDelegatedSession().load(theClass, id);
450                    } catch (RuntimeException ex) {
451                            throw handleException(ex);
452                    }
453            }
454    
455            public Object load(Class theClass, Serializable id, LockMode lockMode) throws HibernateException {
456                    try {
457                            return getDelegatedSession().load(theClass, id, lockMode);
458                    } catch (RuntimeException ex) {
459                            throw handleException(ex);
460                    }
461            }
462    
463            public void load(Object object, Serializable id) throws HibernateException {
464                    try {
465                            getDelegatedSession().load(object, id);
466                    } catch (RuntimeException ex) {
467                            throw handleException(ex);
468                    }
469            }
470    
471            public Object load(String entityName, Serializable id) throws HibernateException {
472                    try {
473                            return getDelegatedSession().load(entityName, id);
474                    } catch (RuntimeException ex) {
475                            throw handleException(ex);
476                    }
477            }
478    
479            public Object load(String entityName, Serializable id, LockMode lockMode) throws HibernateException {
480                    try {
481                            return getDelegatedSession().load(entityName, id, lockMode);
482                    } catch (RuntimeException ex) {
483                            throw handleException(ex);
484                    }
485            }
486    
487            public void lock(Object object, LockMode lockMode) throws HibernateException {
488                    try {
489                            getDelegatedSession().lock(object, lockMode);
490                    } catch (RuntimeException ex) {
491                            throw handleException(ex);
492                    }
493            }
494    
495            public void lock(String entityEntity, Object object, LockMode lockMode) throws HibernateException {
496                    try {
497                            getDelegatedSession().lock(entityEntity, object, lockMode);
498                    } catch (RuntimeException ex) {
499                            throw handleException(ex);
500                    }
501            }
502    
503            public Object merge(Object object) throws HibernateException {
504                    try {
505                            return getDelegatedSession().merge(object);
506                    } catch (RuntimeException ex) {
507                            throw handleException(ex);
508                    }
509            }
510    
511            public Object merge(String entityName, Object object) throws HibernateException {
512                    try {
513                            return getDelegatedSession().merge(entityName, object);
514                    } catch (RuntimeException ex) {
515                            throw handleException(ex);
516                    }
517            }
518    
519            public void persist(Object object) throws HibernateException {
520                    try {
521                            getDelegatedSession().persist(object);
522                    } catch (RuntimeException ex) {
523                            throw handleException(ex);
524                    }
525            }
526    
527            public void persist(String entityName, Object object) throws HibernateException {
528                    try {
529                            getDelegatedSession().persist(entityName, object);
530                    } catch (RuntimeException ex) {
531                            throw handleException(ex);
532                    }
533            }
534    
535            public void reconnect() throws HibernateException {
536                    try {
537                            getDelegatedSession().reconnect();
538                    } catch (RuntimeException ex) {
539                            throw handleException(ex);
540                    }
541            }
542    
543            public void reconnect(Connection conn) throws HibernateException {
544                    try {
545                            getDelegatedSession().reconnect(conn);
546                    } catch (RuntimeException ex) {
547                            throw handleException(ex);
548                    }
549            }
550    
551            public void refresh(Object object) throws HibernateException {
552                    try {
553                            getDelegatedSession().refresh(object);
554                    } catch (RuntimeException ex) {
555                            throw handleException(ex);
556                    }
557            }
558    
559            public void refresh(Object object, LockMode lockMode) throws HibernateException {
560                    try {
561                            getDelegatedSession().refresh(object, lockMode);
562                    } catch (RuntimeException ex) {
563                            throw handleException(ex);
564                    }
565            }
566    
567            public void replicate(Object object, ReplicationMode replicationMode) throws HibernateException {
568                    try {
569                            getDelegatedSession().replicate(object, replicationMode);
570                    } catch (RuntimeException ex) {
571                            throw handleException(ex);
572                    }
573            }
574    
575            public void replicate(String entityName, Object object, ReplicationMode replicationMode) throws HibernateException {
576                    try {
577                            getDelegatedSession().replicate(entityName, object, replicationMode);
578                    } catch (RuntimeException ex) {
579                            throw handleException(ex);
580                    }
581            }
582    
583            public Serializable save(Object object) throws HibernateException {
584                    try {
585                            return getDelegatedSession().save(object);
586                    } catch (RuntimeException ex) {
587                            throw handleException(ex);
588                    }
589            }
590    
591            public void save(Object object, Serializable id) throws HibernateException {
592                    try {
593                            getDelegatedSession().save(object, id);
594                    } catch (RuntimeException ex) {
595                            throw handleException(ex);
596                    }
597            }
598    
599            public Serializable save(String entityName, Object object) throws HibernateException {
600                    try {
601                            return getDelegatedSession().save(entityName, object);
602                    } catch (RuntimeException ex) {
603                            throw handleException(ex);
604                    }
605            }
606    
607            public void save(String entityName, Object object, Serializable id) throws HibernateException {
608                    try {
609                            getDelegatedSession().save(entityName, object, id);
610                    } catch (RuntimeException ex) {
611                            throw handleException(ex);
612                    }
613            }
614    
615            public void saveOrUpdate(Object object) throws HibernateException {
616                    try {
617                            getDelegatedSession().saveOrUpdate(object);
618                    } catch (RuntimeException ex) {
619                            throw handleException(ex);
620                    }
621            }
622    
623            public void saveOrUpdate(String entityName, Object object) throws HibernateException {
624                    try {
625                            getDelegatedSession().saveOrUpdate(entityName, object);
626                    } catch (RuntimeException ex) {
627                            throw handleException(ex);
628                    }
629            }
630    
631            public void setCacheMode(CacheMode cacheMode) {
632                    try {
633                            getDelegatedSession().setCacheMode(cacheMode);
634                    } catch (RuntimeException ex) {
635                            throw handleException(ex);
636                    }
637            }
638    
639            public void setFlushMode(FlushMode value) {
640                    try {
641                            getDelegatedSession().setFlushMode(value);
642                    } catch (RuntimeException ex) {
643                            throw handleException(ex);
644                    }
645            }
646    
647            public void update(Object object) throws HibernateException {
648                    try {
649                            getDelegatedSession().update(object);
650                    } catch (RuntimeException ex) {
651                            throw handleException(ex);
652                    }
653            }
654    
655            public void update(Object object, Serializable id) throws HibernateException {
656                    try {
657                            getDelegatedSession().update(object, id);
658                    } catch (RuntimeException ex) {
659                            throw handleException(ex);
660                    }
661            }
662    
663            public void update(String entityName, Object object) throws HibernateException {
664                    try {
665                            getDelegatedSession().update(entityName, object);
666                    } catch (RuntimeException ex) {
667                            throw handleException(ex);
668                    }
669            }
670    
671            public void update(String entityName, Object object, Serializable id) throws HibernateException {
672                    try {
673                            getDelegatedSession().update(entityName, object, id);
674                    } catch (RuntimeException ex) {
675                            throw handleException(ex);
676                    }
677            }
678    
679            /**
680             * A not to do "if (handler == null)" ping-pong ExceptionHandler version.
681             */
682            private class PingPongExceptionHandler implements ExceptionHandler {
683    
684                    public RuntimeException handle(Throwable ex) {
685                            return (RuntimeException) ex;
686                    }
687    
688            }
689    
690    }