-->
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.  [ 2 posts ] 
Author Message
 Post subject: Thread Local Session: can't get opened session
PostPosted: Fri Nov 07, 2003 11:23 am 
Regular
Regular

Joined: Fri Nov 07, 2003 6:31 am
Posts: 104
Location: Beijing, China
I recently had pbs with this pattern
While trigerring a search form repetitively with the same parameter, I got different results.
I finally found out that the find() method of my DAO was not always using the same session.

When analysing the behavior of the pattern, i realised that it does not always retrieve the existing Session, which lead to inconsistencies.
(it sometimes open a new Session whereas another one is available)

So even when doing the same simple repetitive find() , i'm not systematicaly getting the same object, which of course leads to functionnal mistakes

Here's my code:
Environment:
Jsk1.4.2
Hibernate 2.0.3
Struts1.1
SQLServer

System:
I'm using the Thread Local Session pattern implemented as follow:
Code:
public class ServiceLocator {
    //~ Static fields/initializers =============================================

    public static final ThreadLocal session = new ThreadLocal();
    private static SessionFactory sf = null;
    private static ServiceLocator me;
    private static Log log = LogFactory.getLog(ServiceLocator.class);

    static {
        try {
            me = new ServiceLocator();
        } catch (Exception e) {
            log.fatal("Error occurred initializing ServiceLocator");
            e.printStackTrace();
        }
    }

    //~ Constructors ===========================================================

    private ServiceLocator() throws HibernateException, JDBCException {
        // Try to lookup a JNDI Connection
        try {
            log.debug("Looking up Session in JNDI");
            sf = (SessionFactory) new InitialContext().lookup(org.xx.common.Constants.SESSION_FACTORY);
        } catch (NamingException ne) {
            log.info("error communicating with JNDI, assuming testcase");

            /* If you don't want to specify full class names here and in your DAO's, add
               the following to your hibernate.properties file:
               hibernate.query.imports=org.appfuse.persistence
             */
            sf = new Configuration().addClass(org.xx.adherent.model.Adherent.class)
                    .addClass(org.xx.of.model.Affactureur.class)
                    .addClass(org.xx.adherent.model.CodeFormeJuridique.class)
                    .addClass(org.xx.adherent.model.CodeOrganismeTiersAlternance.class)
                    .addClass(org.xx.of.model.CodeRegroupementOf.class)
                    .addClass(org.xx.profession.model.CodeRisqueNonVersement.class)
                    .addClass(org.xx.of.model.CodeTypeTva.class)
                    .addClass(org.xx.of.model.ConventionCadre.class)
                    .addClass(org.xx.profession.model.NatureFonds.class)
                    .addClass(org.xx.of.model.OrganismeFormation.class)
                    .addClass(org.xx.profession.model.OrganismeTiersCollecteur.class)
                    .addClass(org.xx.profession.model.Profession.class)
                    .addClass(org.xx.adherent.model.Properties.class)
                    .addClass(org.xx.profession.model.RegroupementProfession.class)
                    .addClass(org.xx.user.model.Role.class)
                    .addClass(org.xx.profession.model.Section.class)
                    .addClass(org.xx.adherent.model.StatutCotisation.class)
                    .addClass(org.xx.adherent.model.StatutDemandeFormationSansCotisation.class)
                    .addClass(org.xx.adherent.model.StatutDepassementSeuil.class)
                    .addClass(org.xx.adherent.model.StatutEnvoiBv.class)
                    .addClass(org.xx.adherent.model.StatutNonCotisant.class)
                    .addClass(org.xx.profession.model.TauxCotisation.class)
                    .addClass(org.xx.user.model.User.class)
                    .buildSessionFactory();
        }
    }

    //~ Methods ================================================================

    public static Session currentSession() throws HibernateException {
        Session s = (Session) session.get();
        log.debug("Got hibernate session : "+ s);

        if (s == null) {
            s = sf.openSession();
            log.debug("Opened hibernate session.");
            session.set(s);
        }
        return s;
    }

    public static void closeSession() throws HibernateException, JDBCException {
        Session s = (Session) session.get();
        session.set(null);

        if (s != null) {
            s.close();
            log.debug("Closed hibernate session.");
        }
    }
}


The session are obtained only in the Struts Actions by calling a ActionFilter.getSessions:

Code:
public class ActionFilter implements Filter {

    private static Log log = LogFactory.getLog(ActionFilter.class);
    private FilterConfig filterConfig = null;

    //~ Methods ================================================================

    public void init(FilterConfig filterConfig) throws ServletException {
        this.filterConfig = filterConfig;

    }

    /**
     * Destroys the filter.
     */
    public void destroy() {
        filterConfig = null;
    }

    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain)
    throws IOException, ServletException {
     //do some stuff
    }

    public static Session getSession() throws Exception {
      try {
           return ServiceLocator.currentSession();
      } catch (HibernateException he)
      {
         log.error("Error retrieving an Hibernate Session :" + he.getMessage());
         throw new Exception(he);
      }
    }
}


My DAO method is implemented as follow:
Code:
   public List findObject(Session ses, Class clazz, HashMap map) throws DAOException {
      List classList = null;

      String sql = " 0=0 ";
      Iterator i = map.keySet().iterator();
      while (i.hasNext()) {
         String param = i.next().toString();
         String operator = param.substring(0,1);
            if (operator.compareTo("%")==0) {
               sql = sql + " AND clazz." + param.substring(1) + " like '" + map.get(param) + "%'";
            } else {
               sql = sql + " AND clazz." + param + " = '" + map.get(param) + "'";
            }
      }
      try {
         System.out.println("Sessioon : " +ses);
            classList = ses.find("from clazz in " + clazz + " where " + sql);

      } catch (Exception e) {
         throw new DAOException(e);
      }
      return classList;
   }

NB: I'm not closing the session since it's not necessary when only reading the DB

Here the log I get when i do a repetitive call to this method:
Code:
14:40:14,868 DEBUG ServiceLocator:82 - Got hibernate session : net.sf.hibernate.impl.SessionImpl@24bfaa
14:40:14,868 DEBUG ServiceLocator:82 - Got hibernate session : net.sf.hibernate.impl.SessionImpl@24bfaa
Sessioon : net.sf.hibernate.impl.SessionImpl@24bfaa
search
14:40:16,618 DEBUG ServiceLocator:82 - Got hibernate session : net.sf.hibernate.impl.SessionImpl@24bfaa
14:40:16,618 DEBUG ServiceLocator:82 - Got hibernate session : net.sf.hibernate.impl.SessionImpl@24bfaa
Sessioon : net.sf.hibernate.impl.SessionImpl@24bfaa
search
14:40:17,711 DEBUG ServiceLocator:82 - Got hibernate session : net.sf.hibernate.impl.SessionImpl@24bfaa
14:40:17,711 DEBUG ServiceLocator:82 - Got hibernate session : net.sf.hibernate.impl.SessionImpl@24bfaa
Sessioon : net.sf.hibernate.impl.SessionImpl@24bfaa
search
14:40:18,477 DEBUG ServiceLocator:82 - Got hibernate session : net.sf.hibernate.impl.SessionImpl@24bfaa
14:40:18,477 DEBUG ServiceLocator:82 - Got hibernate session : net.sf.hibernate.impl.SessionImpl@24bfaa
Sessioon : net.sf.hibernate.impl.SessionImpl@24bfaa
search

<this time does not find the session and open a new one. How come??>
14:40:19,024 DEBUG ServiceLocator:82 - Got hibernate session : null
14:40:19,024 DEBUG ServiceLocator:86 - Opened hibernate session.
14:40:19,024 DEBUG ServiceLocator:82 - Got hibernate session : net.sf.hibernate.impl.SessionImpl@1a01e8a
Sessioon : net.sf.hibernate.impl.SessionImpl@1a01e8a
search

Code:
14:40:19,571 DEBUG ServiceLocator:82 - Got hibernate session : net.sf.hibernate.impl.SessionImpl@24bfaa
14:40:19,571 DEBUG ServiceLocator:82 - Got hibernate session : net.sf.hibernate.impl.SessionImpl@24bfaa
Sessioon : net.sf.hibernate.impl.SessionImpl@24bfaa
search
14:40:20,118 DEBUG ServiceLocator:82 - Got hibernate session : net.sf.hibernate.impl.SessionImpl@1a01e8a
14:40:20,118 DEBUG ServiceLocator:82 - Got hibernate session : net.sf.hibernate.impl.SessionImpl@1a01e8a
Sessioon : net.sf.hibernate.impl.SessionImpl@1a01e8a
search
14:40:21,430 DEBUG ServiceLocator:82 - Got hibernate session : net.sf.hibernate.impl.SessionImpl@1a01e8a
14:40:21,430 DEBUG ServiceLocator:82 - Got hibernate session : net.sf.hibernate.impl.SessionImpl@1a01e8a
Sessioon : net.sf.hibernate.impl.SessionImpl@1a01e8a
search


Anyhelp would be more than welcome.
Otherwise i'll have to systematically close all the session, which is not appealing!

cheers,
nodje


Last edited by nodje on Tue Jun 03, 2008 5:28 am, edited 1 time in total.

Top
 Profile  
 
 Post subject:
PostPosted: Fri Nov 07, 2003 12:32 pm 
CGLIB Developer
CGLIB Developer

Joined: Thu Aug 28, 2003 1:44 pm
Posts: 1217
Location: Vilnius, Lithuania
Try to configure logging to print current thread name,
some servlet containers start new thread for "include/forward", you can try java.lang.InheritableThreadLocal as workaround for this problem.


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

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.