-->
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: Session null with hibernate in Webapplication
PostPosted: Tue Aug 22, 2006 9:27 am 
Newbie

Joined: Tue Aug 22, 2006 8:47 am
Posts: 2
Need help with Hibernate? Read this first:
http://www.hibernate.org/ForumMailingli ... AskForHelp

[b]Hibernate version:[3.1]

Hi all iam new bie to Hibernate.

I have an application which runs as standalone and also web application.

For making a generic Persistance which works for standalone and web i have the following Persistance.java file.
Iam able to create sessions and persist data in standalone application.

Iam not able to do when i deploy as web application.

========= Persistance.java ======================
import java.io.*;
import java.util.*;

import javax.servlet.*;

import org.hibernate.SessionFactory;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.hibernate.HibernateException;
import org.hibernate.StaleObjectStateException;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import javax.naming.InitialContext;
import javax.transaction.UserTransaction;

/**
* Filter which manages a ThreadLocal hibernate session. Obtain the session
* by calling Persistence.getSession(). Define the JNDI name of the
* hibernate session factory as an init param to the filter in your web.xml.
*
* Original author Jeff Schnitzer
*
* @version $Id: Persistence.java,v 1.4 2006/03/24 00:27:40 fazeel Exp $
*/

public class Persistence implements Filter
{
private static final long serialVersionUID=1L;

private static Log logger;

/**
* Filter init param which defines the JNDI name for the hibernate factory
*/
public static final String HIBERNATE_FACTORY_JNDI_PARAM = "hibernateFactory";

/**
* Default value if no init param is set.
*/
public static final String HIBERNATE_FACTORY_JNDI_DEFAULT = "java:/SessionFactory";

/**
* Holds the current hibernate session, if one has been created.
*/
protected static ThreadLocal hibernateHolder = new ThreadLocal();
protected static ThreadLocal txHolder = new ThreadLocal();

/**
*/
protected static SessionFactory factory;

/**
* Set to true is we're using Container Manager Persistence (CMP). This
* assumes that we're using JNDI and the Hibernate session factory is registered
* along with a JTA UserTransaction.
*/
private static boolean CMPMode = true;

/**
* JNDI resource name for Hibernate SessionFactory for CMP
*/
public static final String JNDI_HIBERNATE_FACTORY = "SessionFactory";

/**
* JNDI resource name for JTA transaction for CMP
*/
public static final String JNDI_JTA_TRANSACTION = "java:comp/UserTransaction";

/**
* Stored in the request to initiate a rollback
*/
public static final String ROLLBACK = "rollback";
public static final String STALEDATA = "staledata";

/**
* Determine if we're running in container managed persistence context.
* CMPMode cannot be changed externally
* @return True if Hibernate was initialized through the container
*/
public boolean isCMPMode() {
return CMPMode;
}

/**
*/
public void init(FilterConfig filterConfig) throws ServletException {

// Initialize session factory
try {
InitialContext ctx = new InitialContext();
factory = (SessionFactory) ctx.lookup(JNDI_HIBERNATE_FACTORY);
CMPMode = true;
} catch (Exception e) {
// do nothing
}


if (!CMPMode) {
logger.debugLog("Persistence: Init Session: Could not bind to Hibernate Factory through JNDI");
try {
factory = new Configuration().configure().buildSessionFactory();
logger.debugLog("Persistence: Init Session: Hibernate Factory built manually");
} catch (HibernateException ex) {
throw new ServletException(ex);
}
}
}

/**
* Method called by tomcat to apply the filter. Invoked before every servlet is called
* This method manages opening/closing the session and transaction for each servlet.
*/
public void doFilter(ServletRequest request,
ServletResponse response, FilterChain chain)
throws IOException, ServletException {
if (CMPMode)
doFilterCMP(request, response, chain);
else
doFilterHibernate(request, response, chain);
}

/**
* Method called by tomcat to apply the filter. Invoked before every servlet is called
* This method manages opening/closing the session and transaction for each servlet.
*/
private void doFilterCMP(ServletRequest request,
ServletResponse response, FilterChain chain)
throws IOException, ServletException {

UserTransaction tx = null;
try {

tx = (UserTransaction) new InitialContext().lookup(JNDI_JTA_TRANSACTION);
logger.debugLog("=========== ["+Thread.currentThread().hashCode()+"]: dofilter: tx=" + tx);
tx.begin();
try {
// use the Hibernate Factory
//SessionFactory factory = (SessionFactory) new InitialContext().lookup(JNDI_HIBERNATE_FACTORY);

Session sess = factory.openSession();

logger.debugLog("=========== dofilter: sess=" + sess);
hibernateHolder.set(sess);
txHolder.set(tx);
logger.debugLog("=========== dofilter: tx and hib holders set");

chain.doFilter(request, response);
logger.debugLog("=========== dofilter: Returned from chain.dofilter");

String roll = (String) request.getAttribute(ROLLBACK);
if ("true".equals(roll)) {

logger.debugLog("ROLLBACK set to true in request attribute");
request.removeAttribute(ROLLBACK);
rollback();

}
logger.debugLog("Persistence: Commiting");
logger.debugLog("=========== dofilter: About to commit");

tx.commit();

logger.debugLog("=========== dofilter: Committed");
} catch (Exception e) {

logger.debugLog("Persistence: Caught exception during filter chain: " + e);
e.printStackTrace();
} finally {
//hsession.close();
}
} catch (Exception eo) {
eo.printStackTrace();
logger.debugLog("Persistence: Caught exception in tx try: " + eo);
try {
logger.debugLog("Persistence: Rolling back");
tx.rollback();
} catch (Exception rbe) {
logger.debugLog("Persistence: Caught exception while rolling back!!!! " + rbe);
}
}
}

/**
* Method called by tomcat to apply the filter. Invoked before every servlet is called
* This method manages opening/closing the session and transaction for each servlet.
*/
private void doFilterHibernate(ServletRequest request,
ServletResponse response, FilterChain chain)
throws IOException, ServletException {

boolean error = false;

logger.debugLog("Entering doFilter " + Thread.currentThread().hashCode());
if (hibernateHolder.get() != null)

throw new IllegalStateException(
"A session is already associated with this thread! "
+ "Someone must have called getSession() outside of the context "
+ "of a servlet request." + Thread.currentThread().hashCode());

try {
Session sess = factory.openSession();
hibernateHolder.set(sess);
txHolder.set(sess.beginTransaction());
chain.doFilter(request, response);
String roll = (String)request.getAttribute(ROLLBACK);
if ("true".equals(roll)) {
logger.debugLog("ROLLBACK set to true in request attribute");
request.removeAttribute(ROLLBACK);
rollback();
// set error flag to prevent commit
error = true;
}
} catch (Exception ex) {

// if an exception occurs rollback
logger.debugLog("Exception encountered setting error to true and rolling back the transaction");
ex.printStackTrace();
rollback();
// set error flag to prevent commit
error = true;
} finally {
logger.debugLog("closing tx" + Thread.currentThread().hashCode());
Session sess = (Session)hibernateHolder.get();
Transaction tx = (Transaction)txHolder.get();
if (sess != null) {
hibernateHolder.set(null);
try {
if (tx != null && !error) {
logger.debugLog("commiting transaction");
tx.commit();
}
}
catch (HibernateException ex3) {
if (ex3 instanceof StaleObjectStateException) {
logger.debugLog("StaleObjectStateException - set STALEDATA attribute to true");
HttpServletRequest httpRequest = (HttpServletRequest)request;
HttpSession session = httpRequest.getSession();
session.setAttribute(STALEDATA, "true");
}
ex3.printStackTrace();
try {
if (!tx.wasCommitted()) {
rollback();
}
} catch (HibernateException ex4) {
ex4.printStackTrace();
throw new ServletException(ex4);
}
} finally {
try {
logger.debugLog("closing Session " + Thread.currentThread().hashCode());
sess.close();
} catch (HibernateException ex5) {
ex5.printStackTrace();
throw new ServletException(ex5);
}
}
}
logger.debugLog("Successfully closed");
}
}


/**
* @return an appropriate Session object. Not called by client code but by other
* persistence level classes hence throws a HibernateException.
*/
public static Session getSession() throws HibernateException {
Session sess = (Session)hibernateHolder.get();
if (sess == null) {

throw new HibernateException("Session has not been opened -- the session object is NULL");
} else {
//logger.debugLog("Getting session " + Thread.currentThread().hashCode());
}
return sess;
}

/**
* @return the hibernate session factory
*/
public static SessionFactory getSessionFactory() {
logger.debugLog("========== In Persistence.getSessionFactory: sf=" + factory);
return factory;
}

/**
* Commit the transaction. Exceptions thrown as PersistenceExceptions's. This means
* that any Exception handling by the caller needs to invoke the getCause() method
* to get the real exception.
*/
public static void commit() throws PersistenceException {
if (CMPMode)
commitCMP();
else
commitHibernate();
}

/**
* Commit the transaction thru CMP
*/
private static void commitCMP() throws PersistenceException {
try {
logger.debugLog("Persistence: commiting transaction");
UserTransaction tx = (UserTransaction) txHolder.get();
tx.commit();
} catch (Exception e) {
logger.debugLog("Persistence: Cannot commit transaction: rolling back");
rollback();
throw new UpdateException("Persistence: Unable to commit transaction", e);
}
}

/**
* Commit the transaction thru hibernate APIs.
*/
private static void commitHibernate() throws PersistenceException {
try {
Session sess = (Session)hibernateHolder.get();
Transaction tx = (Transaction)txHolder.get();
if (sess != null && tx != null) {
try {
logger.debugLog("Persistence: commiting transaction");
tx.commit();
} catch (HibernateException e) {
e.printStackTrace();
try {
if (!tx.wasCommitted())
rollback();
} catch (HibernateException e2) {
e2.printStackTrace();
throw new UpdateException("Persistence: Unable to commit transaction", e2);
}
throw new UpdateException("Persistence: Unable to commit transaction", e);
}
}
} catch (Exception ex) {
throw new UpdateException("Persistence: Unable to commit transaction", ex);
}
}

/**
* This is a simple method to reduce the amount of code that needs
* to be written every time hibernate is used.
*/
public static void rollback() {
if (CMPMode)
rollbackCMP();
else
rollbackHibernate();
}

/**
* Rollback using CMP
*/
private static void rollbackCMP() {
UserTransaction tx = (UserTransaction) txHolder.get();
txHolder.set(null);
if (tx != null) {
try {
tx.rollback();
logger.debugLog("Rollback successful");
} catch (Exception ex) {
logger.debugLog("Persitence: Ate exception thrown during rollback: " + ex);
// Probably don't need to do anything - this is likely being
// called because of another exception, and we don't want to
// mask it with yet another exception.
}
}
}

/**
* Rollback using Hibernate APIs
*/
private static void rollbackHibernate() {
Transaction tx = (Transaction)txHolder.get();
txHolder.set(null);
if (tx != null) {
try {
tx.rollback();
logger.debugLog("Rollback successful");
} catch (HibernateException ex) {
logger.debugLog("Persitence: Ate exception thrown during rollback: " + ex);
// Probably don't need to do anything - this is likely being
// called because of another exception, and we don't want to
// mask it with yet another exception.
}
}
}


/**
Close the factory
*/
public void destroy() {
if (CMPMode) {
try {
factory.close();
} catch (HibernateException ex) {
throw new RuntimeException(ex);
}
}
}


/**
* This special init method should only be called from stand-alone
* applications that are running outside a web application context.
* The caller is responsible for initializing the DB/Hibernate backend
* and pass in a session factory to Persistence. This is then used by
* the collaborat.db.* and collaborato.dbservice.* to access the database.
* Note that the stand-alone application is required to manage its own
* session/connection logic, the only link to Persistence is to make
* sure that the sessionFactory is available to our persistence layer
* just as if we were running inside a servlet context.
* @param sf Initialized SessionFactory object that will be used by
* the DAO objects
*/
public static void applicationModeInit(SessionFactory sf, Log log)
throws Exception {
// Initialize hibernate
try {
logger = log;
logger.debugLog("Init Session " + Thread.currentThread().hashCode());
factory = sf;
} catch (Exception ex) {
throw new ServletException(ex);
}
}

/**
Invoke this to open a hibernate session.
**/
public static void openSession() throws PersistenceException {

Session sess = (Session)hibernateHolder.get();
if (sess == null) {
logger.debugLog("Opening Session " + Thread.currentThread().hashCode());
try {
sess = factory.openSession();
hibernateHolder.set(sess);
} catch (HibernateException e) {
throw new PersistenceException("Unable to open session", e);
}
} else {
// session already exists
throw new PersistenceException("Session already exists");
}
}

/**
Invoke this method to begin a transaction.
**/
public static void beginTransaction() throws PersistenceException {
Session sess = (Session)hibernateHolder.get();
Transaction tx = (Transaction)txHolder.get();
if (sess == null) {
throw new PersistenceException("Need to call openSession() prior to calling beginTransaction");
} else if (tx == null) {
// creates a new transaction for the current session
try {
if (sess.isConnected()) {
logger.debugLog("beginTransaction: session is connected: disconnect");
sess.disconnect();
logger.debugLog("beginTransaction: disconnect successful");
} else {
logger.debugLog("beginTransaction: no connectione exists");
}
logger.debugLog("beginTransaction: calling reconnect");
sess.reconnect();
logger.debugLog("beginTransaction: reconnect successful");
txHolder.set(sess.beginTransaction());
} catch (HibernateException e) {
throw new PersistenceException("Unable to begin transaction", e);
}
} else {
throw new PersistenceException("Attempting to begin a transaction without ending the previous transaction");
}
return;
}

/**
Invoke this method to end a transaction.
**/
public static void endTransaction() throws PersistenceException {

Session sess = (Session)hibernateHolder.get();
Transaction tx = (Transaction)txHolder.get();
try {
if (sess == null) {
// throw exception
throw new PersistenceException("Attempting to end a transaction when the session is null");
} else if (tx == null) {
throw new PersistenceException("Attempting to end a transaction when there transaction is null");
// throw exception
} else {
commit();
txHolder.set(null);
}
} finally {
try {
if (sess.isConnected()) {
logger.debugLog("endTransaction: connection exists - disconecting");
sess.disconnect();
} else {
logger.debugLog("endTransaction: no connectione exists");
}
logger.debugLog("endTransaction: calling reconnect");
sess.reconnect();
logger.debugLog("endTransaction: reconnect successful");
} catch (Exception e){
throw new PersistenceException("Unable to re-establish a jdbc connection: " + e);
}
}
}

public static void closeSession() throws PersistenceException {

Session sess = (Session)hibernateHolder.get();
Transaction tx = (Transaction)txHolder.get();
if (sess == null) {
throw new PersistenceException("Attempting to close a session that is already null");
}
if (tx != null) {
throw new PersistenceException("Attempting to close a session prior to calling endTransaction()");
}
try {
sess.close();
hibernateHolder.set(null);
} catch (HibernateException e) {
throw new PersistenceException("Unable to close session", e);
}
}

}

================== web.xml =========================
<web-app>
<servlet>
<servlet-name>ABCServlet</servlet-name>
<servlet-class>com.abc.ABCMgr</servlet-class>
</servlet>

<servlet-mapping>
<servlet-name>ABCServlet</servlet-name>
<url-pattern>/ABCMgr</url-pattern>
</servlet-mapping>

<resource-ref>
<res-ref-name>SessionFactory</res-ref-name>
<res-type>net.sf.hibernate.SessionFactory</res-type>
<res-auth>Container</res-auth>
</resource-ref>

<filter>
<filter-name>Persistence</filter-name>
<filter-class>com.abc.persistutils.Persistence</filter-class>
</filter>

<filter-mapping>
<filter-name>Persistence</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>

================== UserDAO =========================
package com.abc.persistence;

import java.util.List;
import javax.naming.InitialContext;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.Query;
import org.hibernate.LockMode;
import org.hibernate.SessionFactory;
import static org.hibernate.criterion.Example.create;

import com.abc.persistutils.Persistence;

/**
* Home object for domain model class User.
* @see com.abc.persistence.User
* @author Hibernate Tools
*/
public class UserDAO {

private static final Log log = LogFactory.getLog(UserDAO.class);

public void persist(User transientInstance) {
log.debug("persisting User instance");
try {
Persistence.getSession().persist(transientInstance);
log.debug("persist successful");
}
catch (RuntimeException re) {
log.error("persist failed", re);
throw re;
}
}

public void attachDirty(User instance) {
log.debug("attaching dirty User instance");
try {
Persistence.getSession().saveOrUpdate(instance);
log.debug("attach successful");
}
catch (RuntimeException re) {
log.error("attach failed", re);
throw re;
}
}

public void attachClean(User instance) {
log.debug("attaching clean User instance");
try {
Persistence.getSession().lock(instance, LockMode.NONE);
log.debug("attach successful");
}
catch (RuntimeException re) {
log.error("attach failed", re);
throw re;
}
}

public void delete(User persistentInstance) {
log.debug("deleting User instance");
try {
Persistence.getSession().delete(persistentInstance);
log.debug("delete successful");
}
catch (RuntimeException re) {
log.error("delete failed", re);
throw re;
}
}

public User merge(User detachedInstance) {
log.debug("merging User instance");
try {
User result = (User) Persistence.getSession()
.merge(detachedInstance);
log.debug("merge successful");
return result;
}
catch (RuntimeException re) {
log.error("merge failed", re);
throw re;
}
}

public User findById( long id) {
log.debug("getting User instance with id: " + id);
try {
User instance = (User) Persistence.getSession()
.get("com.abc.persistence.User", id);
if (instance==null) {
log.debug("get successful, no instance found");
}
else {
log.debug("get successful, instance found");
}
return instance;
}
catch (RuntimeException re) {
log.error("get failed", re);
throw re;
}
}
}

In webapplication I set CMPMode to true for my web application.
For creating sessions iam using servlet filter model, where i create sessions on doFilter().

my servlet has the following code

UserDAO uH = new UserDAO();
User u = new User(login, name, passwd, role, privilege,
null, null, null);
uH.persist(u);

Iam getting an excetion at Persistance.getSession();

when i debug i found that hibernateHolder.get() always returns null.
Iam suprised why Session is null. Can any one help me where iam going wrong.

Thanks in Advance.
Jonny


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.