Results 1 to 6 of 6

Thread: org.hibernate.LazyInitializationException: failed to lazily initialize a collection o

  1. #1

    Default org.hibernate.LazyInitializationException: failed to lazily initialize a collection o

    I've added the OpenSessionInViewFilter to my webapp to handle lazy fetching, but I keep getting an LazyInitializationException. The error log states that the session is closed when a fetch statement is executed through a many-to-many relation.

    This is what I think happens:
    First I'm selecting some categories from a table, and you can see in the log below that this works fine. The only thing is that this takes 1388 milliseconds, which is way too long time...

    This is returned to the view which tries to get all subcategories from each category in a for loop.
    This is where the error happens... The error log states that the session is closed... Why???

    If I don't apply lazy fetching, the code works...

    I've read a lot of threads on different forums, and I have a feeling there is something wrong with my transactions...

    Code:
    INFO: Hibernate: select category0_.CATEGORYID as CATEGORYID16_, category0_.CATEGORY as CATEGORY16_, category0_.CATEGORYLEVEL as CATEGORY3_16_, category0_1_.PARENTID as PARENTID17_ from CATEGORY category0_ left outer join SUBCATEGORY category0_1_ on category0_.CATEGORYID=category0_1_.CHILDID where category0_.CATEGORYLEVEL=1
    INFO: Diff time in ADDRECIPECONTROLLER: 1388
    INFO: Writing CATEGORIES: [beans.Category@1bf00a9, beans.Category@4e23c3, beans.Category@df416]
    SEVERE: failed to lazily initialize a collection of role: beans.Category.subCategoryList, no session or session was closed
    org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: beans.Category.subCategoryList, no session or session was closed
    jsp-file
    Code:
    <c:forEach items="${categories}" var="cat" varStatus="rowCounter">
                        <li class="level_1">
                          <div id="${cat.categoryId}"><c:out value="${cat.category}" /></div>
                         
                          <c:choose>
                            <c:when test="${fn:length(cat.subCategoryList) > 0}">
                              <ul>
                                <c:forEach items="${cat.subCategoryList}" var="subCat" varStatus="rowCounter">
    Category.java
    Code:
    @Entity
    @Table(name = "CATEGORY")
    public class Category implements Serializable {
    
      @Id
      @GeneratedValue(strategy = GenerationType.AUTO)
      @Column(name = "CATEGORYID")
      private Long categoryId;
    
      @ManyToMany
       @JoinTable(name = "SUBCATEGORY",
         joinColumns = { @JoinColumn(name = "PARENTID")},
         inverseJoinColumns = { @JoinColumn(name="CHILDID") })
      private Set<Category> subCategoryList;
    dao-class
    Code:
    public static List getCategories() {
      Session session = HibernateUtil.getSessionFactory().getCurrentSession();
      session.beginTransaction();
       List<Category> categoryList = session.createQuery("select c from Category c where c.categoryLevel=1").list();
    
        session.getTransaction().commit();
        
        return categoryList;
      }

    Controller

    Code:
     long l_1 = System.currentTimeMillis();
    
        List categories = RecipeManager.getCategories(); // calls DAO-class through service class
    
        long l_3 = System.currentTimeMillis() - l_1;
        loggerObj.info("Diff time in ADDRECIPECONTROLLER: " + new Long(l_3).toString() );
    Web.xml
    Code:
    <filter>
        <filter-name>openSessionInViewFilter</filter-name>
        <filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class>
      </filter>
      <filter-mapping>
        <filter-name>openSessionInViewFilter</filter-name>
        <url-pattern>/*</url-pattern>
      </filter-mapping>
    Hibernate.util
    Code:
    public class HibernateUtil {
    
        private static final SessionFactory sessionFactory;
    
        static {
            try {
                // Create the SessionFactory from hibernate.cfg.xml
                sessionFactory = new AnnotationConfiguration().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);
            }
        }
     
        public static SessionFactory getSessionFactory() { 
             return sessionFactory;   
        }
    }
    hibernate.cfg.xml
    Code:
    <hibernate-configuration>
      <session-factory>
        <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
        <property name="dialect">org.hibernate.dialect.MySQLInnoDBDialect</property>
        <property name="connection.url">jdbc:mysql://localhost/foodbase</property>
        <property name="connection.username">root</property>
        <property name="connection.password">admin</property>
    
        <!-- Enable Hibernate's automatic session context management -->
        <property name="current_session_context_class">thread</property>
    
        <!-- Disable the second-level cache  -->
        <property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>
    
        <!-- Echo all executed SQL to stdout -->
        <property name="show_sql">true</property>
        
        <mapping class="beans.Category" />
        <mapping class="beans.SubCategory" />
        
      </session-factory>
    </hibernate-configuration>
    applicationContext.xml
    Code:
    <bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
        <property name="configLocation" value="classpath:hibernate.cfg.xml" />
      </bean>
    Last edited by vator; Apr 10th, 2010 at 02:18 AM.

  2. #2
    Join Date
    Jun 2006
    Location
    The Netherlands
    Posts
    13,695

    Default

    It doesn't work because in the dao you are screwing around with the session yourself, completly bypassing spring in that regard and thus get another session then the one in the OpenSessionINViewFilter. Ergo it isn't going to work.

    This question has been answered numerous times before, I suggest the search.

    1) Don't use that ugly utility of yours
    2) Don't use thread as the current session context, leave it blank
    3) You have 2 sessionfactories due to 1
    4) Configure transactions
    5) (or actually 1) read the chapter about hibernate and spring and transactions of the reference guide.
    Marten Deinum
    Java Consultant / Pragmatist / Open Source Enthousiast / Author


    Pro Spring MVC: With Web Flow
    Conspect

    Have you read the reference guide.
    Use the [ code ] tags, young padawan

  3. #3

    Default

    Thanks for your reply! I have searched the forum, but a lot of the threads are a bit different than my implementation, and therefor not that easy to get ideas from. So could you please help me?

    1) Don't use that ugly utility of yours
    2) Don't use thread as the current session context, leave it blank
    3) You have 2 sessionfactories due to 1
    4) Configure transactions
    5) (or actually 1) read the chapter about hibernate and spring and transactions of the reference guide.


    1) What do you mean? The HibernateUtil class?
    2) If I leave it blank I'm get this errror:org.hibernate.HibernateException: No CurrentSessionContext configured!
    Code:
     <property name="current_session_context_class"></property>
    3) The OSIV-filter needs a sessionFactory to open a new session, right? So I have to configure this in applicationContext.xml. But this is a different one than the HibernateUtil class opens, right? So the OSIV-filter should use the HibernateUtil class to open a new session?
    Could you give me some code on this?

  4. #4
    Join Date
    Jun 2006
    Location
    The Netherlands
    Posts
    13,695

    Default

    1) Yes don't use that ugly utility class
    2) Don't set it remove it completly
    3) No because you shouldn't use that utility class at all and if you want to use it let it use the SessionFactory configured in spring don't let it create its own.
    Marten Deinum
    Java Consultant / Pragmatist / Open Source Enthousiast / Author


    Pro Spring MVC: With Web Flow
    Conspect

    Have you read the reference guide.
    Use the [ code ] tags, young padawan

  5. #5

    Default

    I copied a filter, HibernateSessionRequestFilter that I found in this tutorial: http://community.jboss.org/wiki/OpenSessioninView.

    Now it seems to work, but I'd like to learn how to implement Spring's OSIV-filter too.

    HibernateSessionRequestFilter opens a session through the HibernateUtil class. You want me to delete this class and instead use the config in applicationContext.xml. So is the config in applicationContext.xml right?

    But in th dao class, how do you get the sessionFactory, when you can't get it through the HibernateUtil class?

  6. #6
    Join Date
    Jun 2006
    Location
    The Netherlands
    Posts
    13,695

    Default

    But in th dao class, how do you get the sessionFactory, when you can't get it through the HibernateUtil class?
    That is what is called Dependency Injection, you simply inject the sessionFactory in the dao.
    Marten Deinum
    Java Consultant / Pragmatist / Open Source Enthousiast / Author


    Pro Spring MVC: With Web Flow
    Conspect

    Have you read the reference guide.
    Use the [ code ] tags, young padawan

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •