-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 1 post ] 
Author Message
 Post subject: Question on ThreadLocal Pattern
PostPosted: Fri Jun 23, 2006 4:00 am 
Newbie

Joined: Wed May 24, 2006 5:47 pm
Posts: 14
Hi all.
I'ld like to do a question.. I have tried to use the ThreadLocal Pattern in my application. I have written this Java class:



Code:
import org.apache.log4j.Logger;
import it.eng.hibernate.exception.DBSessionException;
import it.eng.hibernate.exception.TransactionException;
import net.sf.hibernate.FlushMode;
import net.sf.hibernate.HibernateException;
import net.sf.hibernate.Session;
import net.sf.hibernate.SessionFactory;
import net.sf.hibernate.cfg.Configuration;
import net.sf.hibernate.Transaction;

public class DBSessionMgr implements TransactionalResource {

    private static final Logger LOG = Logger.getLogger(DBSessionMgr.class.getName());

    private static ThreadLocal localSession = new ThreadLocal();

    private static ThreadLocal localTransaction = new ThreadLocal();

    private static SessionFactory sessionFactory;

    /**
     * @inheritDoc
     */
    public synchronized void beginTransaction() throws TransactionException {

        if (sessionFactory == null) {
            throw new TransactionException("This transaction resource has not been initialized, please " + "initialize it first.");
        }
        if (localSession != null && localSession.get() != null) {
            LOG.info("Encountered a pending transaction, commiting it before starting a new one.");
            commitTransaction();
        }

        Session session;
        Transaction tx;
        try {
            session = sessionFactory.openSession();
            session.setFlushMode(FlushMode.AUTO);

            tx = session.beginTransaction();
        } catch (HibernateException e) {
            LOG.error("Could not initialize the persistence.", e);
            throw new TransactionException(e);
        }

        localSession.set(session);
        localTransaction.set(tx);
        LOG.info("Beginning transaction with thread : " + Thread.currentThread() + " and session " + session);
    }

    /**
     * @inheritDoc
     */
    public void initialize(String nomeFile) throws TransactionException {

        if (sessionFactory == null) {
            try {
                if (nomeFile == null || nomeFile.trim().equals("")) {

                    LOG.debug("Using default configuration file");
                    sessionFactory = new Configuration().configure().buildSessionFactory();
                } else {

                    LOG.debug("Using this file: [" + nomeFile + "]");
                    sessionFactory = new Configuration().configure(Thread.currentThread().getContextClassLoader().getResource("edilizia.cfg.xml")).buildSessionFactory();
                }
            } catch (HibernateException e) {
                LOG.error("Could not initialize or configure the persistence factory.", e);
                throw new TransactionException(e);
            }
        }
    }

    /**
     * @inheritDoc
     */
    public synchronized void commitTransaction() throws TransactionException {

        Transaction tx = (Transaction) localTransaction.get();
        Session session = (Session) localSession.get();
        try {
            tx.commit();
        } catch (Exception e) {
            LOG.error("Error closing the persistence when committing.", e);
            rollbackTransaction();
            throw new TransactionException(e);
        } finally {
            try {
                session.close();
            } catch (HibernateException e) {
                LOG.fatal("Session could not be closed !!!", e);
            }
            localSession.set(null);
            localTransaction.set(null);
        }
        LOG.info("Commiting transaction with thread : " + Thread.currentThread());

    }

    /**
     * @inheritDoc
     */
    public synchronized void rollbackTransaction() throws TransactionException {

        Transaction tx = (Transaction) localTransaction.get();
        if (tx != null) {
            try {
                tx.rollback();
            } catch (Exception he) {

                LOG.error("Exception while rollbacking", he);
                throw new TransactionException(he);
            }
        }
        LOG.info("Rollbacking transaction with thread : " + Thread.currentThread());
    }

    /**
     * Metodo che controlla se c'è una transazione in atto
     * @return boolean- true se c'è una transazione, false altrimenti.
     */
    public synchronized boolean hasTransaction() {

        if (localSession == null || localSession.get() == null) {
            return false;
        }
        if (localTransaction == null || localTransaction.get() == null) {
            return false;
        }
        return true;
    }

    /**
     * Ritorna la sessione attualmente attiva
     * @return -La sessione di Hibernate
     * @throws DBSessionException -se la sessione o la localsession sono null
     */
    public synchronized static Session getActiveSession() throws DBSessionException {
        if (localSession == null) {
            throw new DBSessionException("No active persistence, the transaction has probably not been initialized " + "in thread " + Thread.currentThread());
        }
        Session session = (Session) localSession.get();
        if (session == null) {
            throw new DBSessionException("No active session, the session has probably not been initialized in thread " + Thread.currentThread());
        }
        return session;
    }

    /**
     * Ritorna la sessione attualmente attiva
     * @return -La sessione di Hibernate
     * @throws DBSessionException -se la sessione o la localsession sono null
     */
    public synchronized static void closeActiveSession() throws DBSessionException {
        if (localSession == null) {
            throw new DBSessionException("No active persistence, the transaction has probably not been initialized " + "in thread " + Thread.currentThread());
        }
        Session session = (Session) localSession.get();
        if (session == null) {
            throw new DBSessionException("No active session, the session has probably not been initialized in thread " + Thread.currentThread());
        }
        try {
            session.close();
        } catch (HibernateException ex) {

            throw new DBSessionException("Exception while closing session in thread " + Thread.currentThread() + " " + ex, ex);
        }
        localSession.set(null);
    }

    public synchronized static boolean hasActiveLocalSession(){

        return ( localSession != null && localSession.get() != null );
    }

    /**
     * Apro la sessione
     * @return -la Sessione
     * @throws DBSessionException -se ci sono errori nel connettersi al DB
     */
    public static Session getDBReadSession() throws DBSessionException {
        Session session = null;
        try {
            session = sessionFactory.openSession();
        } catch (HibernateException e) {
            throw new DBSessionException("Error while opening session. " + e.getMessage(), e);
        }
        return session;
    }

    /**
     * Chiudo la sessione
     * @param session -la sessione da chiudere
     * @throws DBSessionException -Se ci sono errori.
     */
    public static void closeDBReadSession(Session session) throws DBSessionException {
        try {
            session.flush();
            session.close();
        } catch (HibernateException e) {
            throw new DBSessionException("Error while closing session." + e.getMessage(), e);
        }
    }
}


As you can see i use two ThreadLocal properties. Well i have thought to do in this way:
when there is a commit of a transaction in my finally block i close the local session and i empty the ThreadLocal property.
Now i'm new in hibernate and i'ld like to ask if this is a rigth approach in using this pattern or if there is a better way to use this pattern.
Thanks to all.
Angelo[/code]


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 1 post ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.