/** * Copyright (C) 2008-2010, Squale Project - http://www.squale.org * * This file is part of Squale. * * Squale is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation, either version 3 of the * License, or any later version. * * Squale is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Squale. If not, see <http://www.gnu.org/licenses/>. */ package org.squale.jraf.provider.persistence.hibernate; import java.sql.Connection; import java.sql.SQLException; import org.hibernate.HibernateException; import org.hibernate.Transaction; import org.hibernate.Session; import org.hibernate.cfg.Configuration; import org.hibernate.tool.hbm2ddl.SchemaExport; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.squale.jraf.commons.exception.JrafConfigException; import org.squale.jraf.commons.exception.JrafPersistenceException; import org.squale.jraf.commons.exception.JrafRuntimeException; import org.squale.jraf.spi.initializer.IInitializableBean; import org.squale.jraf.spi.persistence.IPersistenceProvider; import org.squale.jraf.spi.persistence.ISession; /** * Objet qui sert � cacher l'impl�mentation d'une session propre au produit de persistence utilis� * Il encapsule la session du produit et une �ventuelle transaction associ� * @author Courtial * @version 2.0 */ public class SessionImpl implements ISession, IInitializableBean { /** log */ private static final Log log = LogFactory.getLog(SessionImpl.class); /** provider de persistance */ private IPersistenceProvider persistenceProvider; /** la session Hibernate */ private Session session = null; /** la transaction Hibernate */ private Transaction tx = null; private boolean isValid = true; /** * Constructeur vide IOC type 2 */ public SessionImpl() { super(); } /** * Constructeur avec parametres IOC type 3. * @param session hibernate * @param provider provider de persistance */ public SessionImpl( Session sess, IPersistenceProvider provider) { this.setSession(sess); this.setPersistenceProvider(provider); this.afterPropertiesSet(); } /** * Retourne la session hibernate * @return Session session hibernate */ public Session getSession() { return session; } /* (non-Javadoc) * @see org.squale.jraf.spi.persistence.ISession#closeSession() */ public void closeSession() throws JrafPersistenceException { if (session != null) { try { if (tx == null) { session.flush(); // on effectue le commit seulement si les transactions // ne sont pas gerees par le conteneur if (!isContainerManagedTransaction() && session.isOpen()) { // FB depuis Hibernate 3 le session.connection() ouvre // une nouvelle connection jdbc avec la base et l'utilisateur // doit la refermer explicitement Connection connection =session.connection(); if(connection.getAutoCommit()) { connection.close(); } else { connection.commit(); } } session.close(); } } catch (HibernateException e) { log.error("Probleme lors de la fermeture la session", e); throw new JrafPersistenceException( "Probleme lors de la fermeture la session", e); } catch (SQLException e) { log.error("Probleme lors de la fermeture la session", e); throw new JrafPersistenceException( "Probleme lors de la fermeture la session", e); } finally { } } else { throw new JrafPersistenceException("Pas de session ouverte"); } } /* (non-Javadoc) * @see org.squale.jraf.spi.persistence.ISession#beginTransaction() */ public void beginTransaction() throws JrafPersistenceException { try { if (tx != null) { throw new JrafPersistenceException("Une transaction est d�j� en cours"); } tx = session.beginTransaction(); } catch (HibernateException e) { if (session != null) { try { session.close(); } catch (HibernateException e1) { throw new JrafPersistenceException( "Probleme lors de la creation d'une transaction", e1); } } throw new JrafPersistenceException( "Probleme lors de la creation d'une transaction", e); } } /* (non-Javadoc) * @see org.squale.jraf.spi.persistence.ISession#commitTransaction() */ public void commitTransaction() throws JrafPersistenceException { if (tx != null) { try { // execution du commit hibernate // en cas de probleme hibernate realise automatiquement le rollback if (log.isDebugEnabled()) { log.debug("Execution du commit hibernate..."); } tx.commit(); if (log.isDebugEnabled()) { log.debug("Commit hibernate OK"); log.debug("Mise de la transaction a null..."); } // la transaction est mise a null car validee par commit tx = null; try { if (log.isDebugEnabled()) { log.debug("Fermeture de la session..."); } session.close(); if (log.isDebugEnabled()) { log.debug("Commit OK"); } } catch (HibernateException e) { String message = "Probleme de fermeture de session apres le commit"; log.error(message, e); throw new JrafPersistenceException(message, e); } } catch (HibernateException e) { String message = "Probleme lors du commit"; log.error(message, e); throw new JrafPersistenceException(message, e); } finally { // rien a faire } } else { log.error("commitTransaction: aucune transaction en cours"); throw new JrafPersistenceException("commitTransaction: aucune transaction en cours"); } } /** * Commit d'une transaction sans fermer la session * @throws JrafPersistenceException */ public void commitTransactionWithoutClose() throws JrafPersistenceException { if (tx != null) { try { // execution du commit hibernate // en cas de probleme hibernate realise automatiquement le rollback if (log.isDebugEnabled()) { log.debug("Execution du commit hibernate..."); } tx.commit(); if (log.isDebugEnabled()) { log.debug("Commit hibernate OK"); log.debug("Mise de la transaction a null..."); } // la transaction est mise a null car validee par commit tx = null; } catch (HibernateException e) { // on propage l'exception String message = "Probleme lors du commit"; log.error(message, e); throw new JrafPersistenceException(message, e); } finally { // rien a faire } } else { log.error("commitTransaction: aucune transaction en cours"); throw new JrafPersistenceException("commitTransaction: aucune transaction en cours"); } } /* (non-Javadoc) * @see org.squale.jraf.spi.persistence.ISession#rollbackTransaction() */ public void rollbackTransaction() { if (tx != null) { try { if (log.isDebugEnabled()) { log.debug("Execution du rollback hibernate..."); } tx.rollback(); if (log.isDebugEnabled()) { log.debug("Rollback hibernate OK"); } } catch (HibernateException e) { log.error("Probleme lors d'un rollback", e); throw new JrafRuntimeException( "Probleme lors d'un rollback", e); } finally { if (log.isDebugEnabled()) { log.debug("Mise de la transaction hibernate a null..."); } tx = null; try { if (log.isDebugEnabled()) { log.debug("Fermeture de la session hibernate..."); } session.close(); if (log.isDebugEnabled()) { log.debug("Rollback OK"); } } catch (HibernateException e1) { log.error( "Probleme lors de la fermeture d'une session lors d'un rollback", e1); } } } else { if (log.isDebugEnabled()) { // aucune transaction String message = "rollbackTransaction: aucune transaction en cours"; log.debug(message); } } } /** * Rollback d'une transaction sans fermeture de session. * La session est reinitialisee pour etre remise en phase avec la base de donnees. */ public void rollbackTransactionWithoutClose() { if (tx != null) { try { if (log.isDebugEnabled()) { log.debug("Execution du rollback hibernate..."); } tx.rollback(); if (log.isDebugEnabled()) { log.debug("Rollback hibernate OK"); } } catch (HibernateException e) { log.error("Probleme lors d'un rollback", e); throw new JrafRuntimeException( "Probleme lors d'un rollback", e); } finally { if (log.isDebugEnabled()) { log.debug("Mise de la transaction hibernate a null..."); } tx = null; // la session est reinitialisee pour revenir a un etat coherent if (log.isDebugEnabled()) { log.debug("Reeinitialisation de la session hibernate..."); } session.clear(); } } else { if (log.isDebugEnabled()) { // aucune transaction String message = "rollbackTransaction: aucune transaction en cours"; log.debug(message); } } } /** * Retourne true si les transactions sont gerees par le conteneur, false sinon * @return true si les transactions sont gerees par le conteneur, false sinon */ public boolean isContainerManagedTransaction() { return getPersistenceProvider().isContainerManagedTransaction(); } /* (non-Javadoc) * @see org.squale.jraf.spi.persistence.ISession#evict(java.lang.Object) */ public void evict(Object object) throws JrafPersistenceException { try { session.evict(object); } catch (HibernateException e) { throw new JrafPersistenceException(e); } } /** * Execute un flush sur la session hibernate */ public void flush() throws JrafPersistenceException { try { session.flush(); } catch (HibernateException e) { throw new JrafPersistenceException(e); } } /* (non-Javadoc) * @see org.squale.jraf.spi.persistence.ISession#contains(java.lang.Object) */ public boolean contains(Object object) { return session.contains(object); } /* (non-Javadoc) * @see org.squale.jraf.spi.persistence.ISession#clear() */ public void clear() { session.clear(); } public SchemaExport getSchemaExport() { if (log.isDebugEnabled()) { log.debug("getSchemaExport() - start"); } SchemaExport sExport = null; try { Configuration cf = new Configuration().configure(); sExport = new SchemaExport(cf); } catch (Exception e) { log.error("getSchemaExport()", e); } if (log.isDebugEnabled()) { log.debug("getSchemaExport() - end"); } return sExport; } /* (non-Javadoc) * @see org.squale.jraf.spi.persistence.ISession#isOpen() */ public boolean isOpen() { // si pas de session retourne false if (session == null) { return false; } // retourne l'etat d'ouverture de la session return session.isOpen(); } /** * Retourne true si la session est liee a une connexion jdbc, false sinon * @return true si la session est liee a une connexion jdbc, false sinon */ public boolean isConnected() { // si pas de session retourne false if (session == null) { return false; } // retourne l'etat de connexion de la session return session.isConnected(); } /** * @param session */ public void setSession(org.hibernate.Session sess) { this.session = sess; } /* (non-Javadoc) * @see org.squale.jraf.spi.initializer.IInitializableBean#afterPropertiesSet() */ public void afterPropertiesSet() { if (getSession() == null) { throw new JrafConfigException("La session hibernate ne peut etre 'null'"); } if (getPersistenceProvider() == null) { throw new JrafConfigException("Le provider de persistance ne peut etre 'null'"); } } /** * Retourne le provider de persistance * @return provider de persistance */ public IPersistenceProvider getPersistenceProvider() { return persistenceProvider; } /** * Renseigne le provider de persistance * @param provider provider de persistance */ public void setPersistenceProvider(IPersistenceProvider provider) { persistenceProvider = provider; } /** * Retourne true si il y a une transaction en cours sur cette session * Retourne false sinon. * @return true si il y a une transaction en cours sur cette session, false sinon */ public boolean isInTransaction() { return (tx != null); } /* (non-Javadoc) * @see org.squale.jraf.spi.persistence.ISession#invalidate() */ public void invalidate() { isValid=false; } /* (non-Javadoc) * @see org.squale.jraf.spi.persistence.ISession#isValid() */ public boolean isValid() { return isValid; } }