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: managing sessions in non-transactional context
PostPosted: Thu Feb 22, 2007 12:14 am 
Newbie

Joined: Fri Jan 26, 2007 10:13 pm
Posts: 9
Need help with Hibernate? Read this first:
http://www.hibernate.org/ForumMailingli ... AskForHelp

Hibernate version: 3.2.2 GA

Name and version of the database you are using: Db2 7.2 .5

J2EE Application Server : Webpshere 6.0.2.15

Hi,

We are using a customized HibernateUtil class which is used by both transactional and non-transactional stateless session beans methods.

Here is our code of the HibernateUtil
-------------------------------------------------
package com.customer.ruby.utils.hibernate;

import java.sql.Timestamp;

import javax.transaction.Transaction;
import javax.transaction.TransactionManager;

import org.apache.log4j.Logger;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.engine.SessionFactoryImplementor;
import org.hibernate.util.JTAHelper;

/**
* Basic Hibernate helper class.
* Handles SessionFactory, Session and Transaction.
* <p>
* Uses a static initializer for the initial SessionFactory creation
* and holds Session and Transactions in thread local variables. All
* exceptions are wrapped in RUBYBusinessException.
*
*/
public class HibernateUtil {

private static final Logger logger = Logger.getLogger(HibernateUtil.class);

private static Configuration configuration;
private static SessionFactory sessionFactory;

private static TimestampSynchronization iTsSyn = null;

private static final ThreadLocal threadSession = new ThreadLocal();
private static final ThreadLocal threadTimeStamp = new ThreadLocal();

// Create the initial SessionFactory from the default configuration files or JNDI
static {
try {
configuration = new Configuration();
sessionFactory = configuration.configure("RUBYHibernate.cfg.xml")
.buildSessionFactory();
iTsSyn = new TimestampSynchronization(threadTimeStamp);
} catch (Throwable ex) {
// Log exceptions
logger.error("Building SessionFactory failed.", ex);
throw new ExceptionInInitializerError(ex);
}
}

/**
*
*/
private HibernateUtil() {
super();
}

/**
* Returns the SessionFactory used for this static class.
*
* @return SessionFactory
*/
public static SessionFactory getSessionFactory() {
return sessionFactory;
}

/**
* Returns the original Hibernate configuration.
*
* @return Configuration
*/
public static Configuration getConfiguration() {
return configuration;
}

/**
* Rebuild the SessionFactory with the static Configuration.
*
*/
public static void rebuildSessionFactory() throws HibernateException {
synchronized (sessionFactory) {
try {
sessionFactory = getConfiguration().buildSessionFactory();
} catch (Exception ex) {
throw new HibernateException(ex);
}
}
}

/**
* Rebuild the SessionFactory with the given Hibernate Configuration.
*
* @param cfg
*/
public static void rebuildSessionFactory(Configuration cfg)
throws HibernateException {
synchronized (sessionFactory) {
try {
sessionFactory = cfg.buildSessionFactory();
configuration = cfg;
} catch (Exception ex) {
throw new HibernateException(ex);
}
}
}

/**
* Retrieves the current Session local to the thread. <p/>If no Session is
* open, opens a new Session for the running thread.
*
* @return Session
*/
public static Session getSession() throws HibernateException {
Session sess = null;
SessionFactory sFactory = getSessionFactory();

try {

TransactionManager transactionManager = ((SessionFactoryImplementor)sFactory).getTransactionManager();
Transaction txn = null;

// Logs an error message if Transaction Manager is not found
if (transactionManager == null) {
logger.error( "No Transaction Manager found. Proceeding without transaction manager...");
}
else {
// Retrieves the Transaction associated with the current thread of execution
txn = transactionManager.getTransaction();
}

/*
* Checks if Transaction is NULL or NOT in progress, Returns
* the session in the threadSession Threadlocal instance
*/
if (txn == null || !JTAHelper.isInProgress(txn.getStatus())) {

sess = (Session)threadSession.get();
if(sess == null) {
/*
* Instatiates a new session if no existing session instance is found
* and sets it to the threadSession ThreadLocal instance in the current thread
*/
sess = sFactory.openSession();
threadSession.set(sess);
}
}
/*
* if Transaction is NOT NULL or in progress, returns the current session
*/
else {
sess = sFactory.getCurrentSession();
// Regsitering the TimestampSynchronization instance with the Transaction
txn.registerSynchronization(iTsSyn);

/*
* Populating the ThreadLocal threadTimestamp with the current Timestamp
*/
if(threadTimeStamp.get() == null) {
threadTimeStamp.set(new Timestamp(System.currentTimeMillis()));
}
}
return sess;
}
catch (HibernateException ex) {
throw new HibernateException(ex);
}
catch (Throwable t) {
throw new HibernateException( "Problem locating/validating JTA transaction", t );
}
}

/**
* @return
*/
public static Timestamp getThreadTimestamp() {
Timestamp ts = (Timestamp)threadTimeStamp.get();
return ts;
}
}
------------------------------------------------------------------------------------

For non-transactional situations we are using threadlocal to store the hibernate session. While it's simple to set it to the Threadlocal object when the session is not available, it's becoming a pain to remove it from the threadlocal instance when the bean call completes and the unsupported session bean method returns. On a subsequent call it's picking up stale value from the previous session and messing everything up. I did found some examples in the forum, esp the OpenSessionInviewFilter approach looked promising but we have strict separation of web layer and business layer where the hibernate POJOs resides. So servlet filter is ruled out. AOP looks complex and we are not using JBOSS anyway. We are using WebSphere 6.x. We do not have a have a JTA transaction either in hand to use the Synchronization interface since it's a unsupported session bean method

Any ideas, folks?


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.