Announcement Announcement Module
Collapse
No announcement yet.
Hibernate - Lazy Load exception - no session or session was closed Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Hibernate - Lazy Load exception - no session or session was closed

    I am sure that this has been talked about 200 times. But I could not get the answer's in other items.

    The Exception I am getting

    org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: org.webscale.spring.model.User.transactions, no session or session was closed
    My code is as follows
    The Test Case:

    Code:
    public void testaddTransaction(){
    		try{
    		List<User> users = mapper.loadUserByName("XXX");
    		User user = users.get(0);
    
    		Transaction t = new Transaction();
    		t.setType("haha");
    		t.setUser(user);
    		user.addTransaction(t);
    		mapper().saveUser(user);
    	
    		}catch (Exception e) {
    			log.error("err" , e);
    			super.fail();
    		}
    		
    	}
    The Mapper


    Code:
    public class GenericMapper  {
        private HibernateTemplate hibernateTemplate;
    	public GenericMapper(){
    		super();
    	}
    	
    	public void setSessionFactory(SessionFactory sessionFactory) {
            this.hibernateTemplate = new HibernateTemplate(sessionFactory);
        }
    
    	public void saveUser(User user){
    		hibernateTemplate.saveOrUpdate(user);
    	}
        public List<User> loadUserByName(String name) {
        	return this.hibernateTemplate.find("from User user where user.name=?", name);
        }
    }
    User and Transactions is a simple 1 to Many relationship:

    Here is the hibernate mapping for user
    Code:
    <hibernate-mapping>
        <class name="org.webscale.spring.model.User" table="user" schema="public">
            <id name="id" type="int">
                <column name="id" />
               	<generator class="sequence">
      					<param name="sequence">user_id_seq</param> 
    			</generator>
            </id>
            <property name="name" type="string">
                <column name="name" />
            </property>
            <set name="transactions" inverse="true" lazy="true" cascade="all">
                <key>
                    <column name="userid" />
                </key>
                <one-to-many class="org.webscale.spring.model.Transaction" />
            </set>
        </class>
    </hibernate-mapping>

    Here is the Hibernate Mapping for Transaction
    Code:
    <hibernate-mapping>
      <class name="org.webscale.spring.model.Transaction" table="transactions" schema="public">
      <id name="id" type="int">
                <column name="id" />
                <generator class="sequence">
      					<param name="sequence">transactions_id_seq</param> 
    			</generator>
            </id>
            <many-to-one name="user" class="org.webscale.spring.model.User" fetch="select">
                <column name="userid" />
            </many-to-one>
            <property name="type" type="string">
                <column name="type" />
            </property>
        
      </class>
    </hibernate-mapping>
    What Am I doing wrong ?
    Last edited by webscale; Aug 13th, 2008, 06:50 PM. Reason: better title

  • #2
    same problem in hibernate spring one to many association

    Hi Springy
    I am facing the same problem.My SchoolHBean has a set and StudentHBean has an instance of SchoolHBean.When i am retiving StudentHBean using SchoolHBean instance ,I am getting the Error that session has been closed.I am pasting my corresponding files here.Please help me out.
    Thanks
    Raj Kamal
    MyController class is
    Code:
    public class MappingCheckController extends SimpleFormController {
    ......
    @Override
    	protected Object formBackingObject(HttpServletRequest request) throws Exception {
    
    System.out.println("Insid ethe controller--MappingCheckController");
    		SchoolHBean teo = new SchoolHBean();
    		CommonUtility utility = new CommonUtility();
    		utility.testMapping();
    		System.out.println("Insid ethe controller333333333--MappingCheckController");
    		
        	return teo;
        }
    CommonUtility .java

    Code:
    public void testMapping(){
    		System.out.println("Insid ethe controller--dao");
    		dao.testMapping();
    		System.out.println("Insid ethe controller--complr5555");
    	}
    MYDao class is
    Code:
    public class CommonDao extends HibernateDaoSupport {
    
    public void testMapping(){
    		System.out.println("Inside the method of the dao for mapping");
    
    SchoolHBean teo =null;
    		List<SchoolHBean> list1 = getHibernateTemplate().find("from SchoolHBean");
    		if(list1.size() > 0 && list1.get(0)!= null){
             	 for(Iterator itr=list1.iterator();itr.hasNext();){
             		 teo = new SchoolHBean();
             		 teo = (SchoolHBean)itr.next();
             		 System.out.println("Hi inside the verify record --->"+teo.getAddress());
             	 }
             }
    		StudentHBean hb = null;
    		Set ss = teo.getStudents();
    		Iterator itr2 = ss.iterator();
    		 while(itr2.hasNext()){
    			 hb= (StudentHBean)itr2.next();
    			  System.out.println("Data displaying ---"+hb.getStudentName());
    		  }
    		 
    	}
    MY sample-servlet.xml file is as follows
    Code:
    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
     
      
      
      <!-- For spring hibernate Integration started -->
       <bean id="dataSource"
    		class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    		<property name="driverClassName">
    			<value>org.postgresql.Driver</value>
    		</property>
    		<property name="url">
    			<value>jdbc:postgresql://localhost:5432/mappingTestDB</value>
    		</property>
    		<property name="username">
    			<value>postgres</value>
    		</property>
    		<property name="password">
    			<value>[email protected]#</value>
    		</property>
    	</bean>
    	
      <bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
            <property name="dataSource">
            	<ref local="dataSource"/>
            </property>
            
      		<property name="mappingResources">
      			<list> 
                	 <value>cghs/commons/claims/teo1/StudentHBean.hbm.xml</value> 
                	 <value>cghs/commons/claims/teo1/SchoolHBean.hbm.xml</value> 
                </list>
            </property>
            <property name="hibernateProperties">
                <props>
                    <prop key="hibernate.dialect">org.hibernate.dialect.PostgreSQLDialect</prop>
                    <prop key="hibernate.show_sql">true</prop>
                    <prop key="hibernate.generate_statistics">true</prop>
             <!--   <prop key="hibernate.hbm2ddl.auto">create</prop> -->
                </props>
            </property>
            </bean>
            <bean id="openView" class="org.springframework.orm.hibernate3.support.OpenSessionInViewFilter" />
            
         <bean id="userDAO" class="cghs.commons.claims.dao.CGHSCommonDao">
    			<property name="sessionFactory">
    				<ref local="sessionFactory"/>
    			</property>
    		</bean> 
    	
    	 <bean id="transactionManager" 
    			class="org.springframework.orm.hibernate3.HibernateTransactionManager">
    			<property name="sessionFactory">
    					<ref local="sessionFactory"/>
    			</property>
    	</bean> 
      <bean name="/mappingCheck.html" class="cghs.commons.claims.action.MappingCheckController">
      <property name="commandClass" value="cghs.commons.claims.teo1.SchoolHBean" />
      <property name="formView" value="successPage" />
      <property name="successView" value="hello_world.html"/>
      </bean>
    
     <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
          <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
          <property name="prefix" value="/jsp/"/>
          <property name="suffix" value=".jsp"/>
      </bean>
     
    </beans>
    My HBms are as follows
    1.StudentHbean.hbm.xml
    Code:
      <?xml version="1.0" encoding="UTF-8"?>
    
    <!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN" 
        "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
    
    <hibernate-mapping
    >
        <class
            name="cghs.commons.claims.teo1.StudentHBean"
            table="Student"
        >
    
            <id
                name="id"
                column="id"
                type="int"
            >
                <!--  <generator class="native">
                  
                      To add non XDoclet generator parameters, create a file named 
                      hibernate-generator-params-StudentHBean.xml 
                      containing the additional parameters and place it in your merge dir. 
                 
                </generator>  --> 
            </id>
    
            <many-to-one
                name="school"
                class="cghs.commons.claims.teo1.SchoolHBean"
                cascade="save-update"
                outer-join="true"
                update="true"
                insert="true"
                column="SCHOOL_ID"
            />
    
            <property
                name="studentName"
                type="java.lang.String"
                update="true"
                insert="true"
                column="studentName"
                length="100"
            />
    
        </class>
    
    </hibernate-mapping>
    2.SchoolHBean.hbm.xml
    Code:
    <?xml version="1.0" encoding="UTF-8"?>
    
    <!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN" 
        "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
    
    <hibernate-mapping
    >
        <class
            name="commons.claims.teo1.SchoolHBean"
            table="School"
            lazy="true"
        >
    
            <id
                name="id"
                column="id"
                type="int"
            >
              <!--    <generator class="native">
                  
                      To add non XDoclet generator parameters, create a file named 
                      hibernate-generator-params-SchoolHBean.xml 
                      containing the additional parameters and place it in your merge dir. 
                 
                </generator>  --> 
            </id>
    
            <property
                name="address"
                type="java.lang.String"
                update="true"
                insert="true"
                column="address"
                length="100"
            />
    
            <property
                name="schoolName"
                type="java.lang.String"
                update="true"
                insert="true"
                column="schoolName"
                length="100"
            />
    
            <set
                name="students"
                lazy="true"
                cascade="save-update"
                sort="unsorted"
            >
    
                <key
                    column="SCHOOL_ID"
                >
                </key>
    
                <one-to-many
                      class="commons.claims.teo1.StudentHBean"
                />
    
            </set>
    
        </class>
    
    </hibernate-mapping>
    My pojos are as follows
    Code:
    package commons.claims.teo1;
    
    import java.util.HashSet;
    import java.util.Set;
    
    
    
    public class SchoolHBean {
    
    	private int id;
    
    	private String schoolName;
    
    	private String address;
    
    	private Set students = new HashSet();
    
    		public String getAddress() {
    		return address;
    	}
    
    	public void setAddress(String address) {
    		this.address = address;
    	}
    
    		public int getId() {
    		return id;
    	}
    
    	public void setId(int id) {
    		this.id = id;
    	}
    
    		public String getSchoolName() {
    		return schoolName;
    	}
    
    	public void setSchoolName(String schoolName) {
    		this.schoolName = schoolName;
    	}
    
    		public Set getStudents() {
    		return students;
    	}
    
    	public void setStudents(Set students) {
    		this.students = students;
    	}
      	
    	
    }
    and another pojo is
    Code:
    package commons.claims.teo1;
    
    /**
     * @hibernate.class table="Student"
     * @author Vikas.Goel
     * 
     */
    public class StudentHBean {
    
    	private int id;
    
    	private String studentName;
    
    	private SchoolHBean school;
    
    	/**
    	 * @hibernate.id generator="native"
    	 * @return
    	 */
    	public int getId() {
    		return id;
    	}
    
    	public void setId(int id) {
    		this.id = id;
    	}
    
    	/**
    	 * @hibernate.many-to-one
    	 *  outer-join="true"
    	 *  cascade="save-update"
    	 *  column="SCHOOL_ID"
    	 * @return
    	 */
    	public SchoolHBean getSchool() {
    		return school;
    	}
    
    	public void setSchool(SchoolHBean school) {
    		this.school = school;
    	}
    
    	/**
    	 * @hibernate.property length="100"
    	 * @return
    	 */
    	public String getStudentName() {
    		return studentName;
    	}
    
    	public void setStudentName(String studentName) {
    		this.studentName = studentName;
    	}
    
    }
    Any help in this regard will higly be appreciated.

    Thanks once again.

    Comment


    • #3
      To be able to retreive rows with lazy loading the session must still be active. That means it cannot leave the transaction manager. Either turn off lazy loading or do the operations in a service object

      Comment


      • #4
        Hi
        thnaks For ur reply.Can u give an example or rectify my code.

        Thanks

        Comment


        • #5
          Just make your methods transactional.
          Create aspect with <tx:advice> or @Transactional with <context:annotation-config>

          Comment


          • #6
            Maybe this will work

            This is what I did to overcome the no session problem with LazyFetch . I am using Hibernate + JPA + Spring

            ApplicationContext context = new FileSystemXmlApplicationContext( Your Application Context );
            EntityManagerFactory emf = (EntityManagerFactory) context.getBean("entityManagerFactory");
            EntityManager em = emf.createEntityManager(); TransactionSynchronizationManager.bindResource(emf , new EntityManagerHolder(em));

            Comment


            • #7
              Originally posted by dawalama View Post
              This is what I did to overcome the no session problem with LazyFetch . I am using Hibernate + JPA + Spring

              ApplicationContext context = new FileSystemXmlApplicationContext( Your Application Context );
              EntityManagerFactory emf = (EntityManagerFactory) context.getBean("entityManagerFactory");
              EntityManager em = emf.createEntityManager(); TransactionSynchronizationManager.bindResource(emf , new EntityManagerHolder(em));
              it could work but use internal Spring mechanism - it is just a hack...

              I am repeating: wrap your method in transaction.

              Comment

              Working...
              X