-->
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.  [ 5 posts ] 
Author Message
 Post subject: Session is closed!
PostPosted: Fri Dec 07, 2007 4:41 am 
Newbie

Joined: Fri Dec 07, 2007 4:25 am
Posts: 2
Hi Guys,
Hope you can help me out with this. I've recently switched to Hibernate and this problem keeps cropping up. Here's the problem code: (slightly paraphrased
Code:
QuestionManager qm = new QuestionManager();
LearningNodeManager lnm = new LearningNodeManager();
LearningNode ln = null;
Question q1 = null;

ln = lnm.getNode(1); //gets node 1 from db
q1 = new Question("title1", "question1", ln);
qm.insertQuestionIntoDB(q1);
         


I think because it accesses the DB with 1 session to get the Learning Node, and another for the question, I get the following exception:
Code:

org.hibernate.SessionException: Session was already closed
   at org.hibernate.impl.SessionImpl.close(SessionImpl.java:275)
   at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
   at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
   at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
   at java.lang.reflect.Method.invoke(Unknown Source)
   at org.hibernate.context.ThreadLocalSessionContext$TransactionProtectionWrapper.invoke(ThreadLocalSessionContext.java:301)
   at $Proxy0.close(Unknown Source)
   at com.samatkinson.structures.QuestionManager.insertQuestionIntoDB(QuestionManager.java:144)
   at com.samatkinson.servlets.Tutor.NodeManagerServlet.saveQuestion(NodeManagerServlet.java:98)
   at com.samatkinson.servlets.Tutor.NodeManagerServlet.doPost(NodeManagerServlet.java:65)
   at javax.servlet.http.HttpServlet.service(HttpServlet.java:710)
   at javax.servlet.http.HttpServlet.service(HttpServlet.java:803)...


I'll put the hibernate and class files below. My Basic question is, a) how do I fix this, and b) What is the permanent solution for using managers like this to control DB access, as it keeps cropping up. Normally setting lazy="false" works, but it hasn't this time.

Cheers!!

LearningNode.hbm.xml:
Code:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">


<hibernate-mapping>
   <class name="com.samatkinson.structures.graph.LearningNode"
      table="learning_nodes" lazy="false">

      <id name="id" column="node_id" type="java.lang.Integer">
         <generator class="increment" />
      </id>
      <property name="name" />
      <property name="info" />
      <!-- put stuff in here for owner -->

      <many-to-one name="owner"
         class="com.samatkinson.structures.User" column="owner_id" />
         
      <bag name="children" table="children" lazy="false">
         <key column="parent_id" />
         <many-to-many column="child_id"
            class="com.samatkinson.structures.graph.LearningNode" />
      </bag>
      <bag name="parents" table="children" lazy="false" inverse="true">
         <key column="child_id" />
         <many-to-many column="parent_id"
            class="com.samatkinson.structures.graph.LearningNode" />
      </bag>
      <bag name="registered" table="registered" lazy="false">
         <key column="node_id" />
         <many-to-many column="user_id"
            class="com.samatkinson.structures.User" />
      </bag>
      <bag name="questions" table="questions" lazy="false" inverse="true">
         <key column="question_id" />
         <one-to-many
            class="com.samatkinson.structures.Question"/>
      </bag>
      
   </class>
</hibernate-mapping>


Question.hbm.xml
Code:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">


<hibernate-mapping>
   <class name="com.samatkinson.structures.Question"
      table="questions" lazy="false">

      <id name="id" column="question_id" type="java.lang.Integer">
         <generator class="increment" />
      </id>
      <property name="title"/>
      <property name="question" />
      
   
      <!-- put stuff in here for owner -->

      <many-to-one name="node"
         class="com.samatkinson.structures.graph.LearningNode" column="node_id" lazy="false" />
      
   </class>
</hibernate-mapping>


Relevant part of LearningNodeManager:
Code:
public LearningNode getNode(int nodeNumber)
         throws LearningNodeNotFoundException {
      LearningNode ln = null;
      Session session = null;
      Transaction tx1 = null;
      try {
         session = HibUtil.getSession();
         tx1 = session.beginTransaction();
         Query query = session
               .createQuery("from LearningNode ln where ln.id = :nodeNumber");
         query.setParameter("nodeNumber", nodeNumber);
         for (Iterator<LearningNode> it = query.iterate(); it.hasNext();) {
            ln = it.next();
         }
         tx1.commit();
      } catch (HibernateException he) {
         he.printStackTrace();
         if(tx1!=null)tx1.rollback();
      }
      if (ln != null) {
         return ln;
      } else {
         // will only reach here if no user found
         throw new LearningNodeNotFoundException(
               "Learning node with number " + nodeNumber + "not found.");
      }
   }


Relevant part of Question Manager:
Code:
public boolean insertQuestionIntoDB(Question question) {
      try {
         Session session = HibUtil.getSession();
         Transaction tx = session.beginTransaction();
         session.save(question);
         tx.commit();
         session.close();
         return true;
      } catch (ConstraintViolationException cve) {
         cve.printStackTrace();
         System.out.println(cve.getConstraintName());
         cve.getSQLException();
         return false;
      } catch (HibernateException he) {
         he.printStackTrace();

         return false;

      }
   }


HibUtil:
Code:
package com.samatkinson.utils;

import org.hibernate.*;
import org.hibernate.cfg.*;

// TODO: Auto-generated Javadoc
/**
* The Class HibUtil.
*/
public class HibUtil {

    /** The Constant sessionFactory. */
    private static final SessionFactory sessionFactory;

    static {
        try {
            // Create the SessionFactory from hibernate.cfg.xml
            sessionFactory = new Configuration().configure().buildSessionFactory();
        } catch (Throwable ex) {
            // Make sure you log the exception, as it might be swallowed
            System.err.println("Initial SessionFactory creation failed." + ex);
            throw new ExceptionInInitializerError(ex);
        }
    }

    /**
     * Gets the session factory.  The session Factory should only exist once
     * per session, as a result this hibutil returns the factory, or instantiates it
     * if it's the first call.
     *
     * @return the session factory
     */
    public static SessionFactory getSessionFactory() {
        return sessionFactory;
    }
    public static Session getSession(){
       return HibUtil.getSessionFactory().getCurrentSession();}

}

If you need anything else just let me know. Cheers!! Any help you can offer will be greatly appreciated.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Dec 07, 2007 5:55 am 
Expert
Expert

Joined: Thu May 26, 2005 9:19 am
Posts: 262
Location: Oak Creek, WI
Hi,

Try to close the session in getNode method. I feel this might be because of concurrency.

_________________
RamnathN
Senior Software Engineer
http://www.linkedin.com/in/ramnathn
Don't forget to rate.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Dec 07, 2007 6:35 am 
Newbie

Joined: Fri Dec 07, 2007 4:25 am
Posts: 2
Afraid that didn't work.

When committing the transaction (tx.commit()) it closes the session. When adding the session.close() line, it throws the following:

Code:
org.hibernate.SessionException: Session was already closed


as a result of it already being closed.

From what I can tell, when you get an object from the database, it is associated with the session. However, when you commit the transaction, it closes the session. When I then try and insert the Question into the database, it needs to update the LearningNode (due to the one-to-many relationship), however it's session is already closed which is why the errors caused.

Anyone who can help, I'll be forever thankful!!


Top
 Profile  
 
 Post subject:
PostPosted: Fri Dec 07, 2007 8:57 am 
Regular
Regular

Joined: Mon Mar 26, 2007 12:38 am
Posts: 119
Hi,
Replace
public static Session getSession(){
return HibUtil.getSessionFactory().getCurrentSession();
}


With
public static Session getSession(){
return HibUtil.getSessionFactory().openSession();
}


--------------------------------------------------
Rate the reply if you find it helpful


Top
 Profile  
 
 Post subject:
PostPosted: Mon Dec 10, 2007 5:19 am 
Newbie

Joined: Tue Nov 20, 2007 4:57 am
Posts: 7
Hey

Try synchronizing all the methods which access the database directly, it worked for me


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 5 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.