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...
jsp-fileCode: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
Category.javaCode:<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">
dao-classCode:@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;
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
Web.xmlCode: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() );Hibernate.utilCode:<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.cfg.xmlCode: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; } }
applicationContext.xmlCode:<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>
Code:<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean"> <property name="configLocation" value="classpath:hibernate.cfg.xml" /> </bean>


Reply With Quote
