Wednesday, June 22, 2011

failed to lazily initialize a collection of role: Hibernate Session Ends before reaching View

Problem: Use of Lazy loading and accessing a collection of results from the JSP (view ) results int he following JasperException
org.apache.jasper.JasperException: org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.smartshop.dao.Product.productAvailability, no session or session was closed org.apache.jasper.servlet.JspServletWrapper.handleJspException(JspServletWrapper.java:500) org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:428) org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:313) org.apache.jasper.servlet.JspServlet.service(JspServlet.java:260) javax.servlet.http.HttpServlet.service(HttpServlet.java:717) org.springframework.web.servlet.view.InternalResourceView.renderMergedOutputModel(InternalResourceView.java:238) org.springframework.web.servlet.view.AbstractView.render(AbstractView.java:250) org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1047) org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:817) org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:719) org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:644) org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:549) javax.servlet.http.HttpServlet.service(HttpServlet.java:617) javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
Technologies: Spring, Hibernate, MySQL

Reason :  Lazy Loading makes Hibernate to not load the data until it is called for. The Hibernate Session in Spring by default ends long before it reaches the View level. So, when you try to access the uninitialized objects from the View, above exception is thrown.

Solution: In your spring-servlet.xml add the following bean:


<bean class="org.springframework.orm.hibernate3.support.OpenSessionInViewInterceptor" name="openSessionInViewInterceptor">
<property name="sessionFactory" ref="sessionFactory"></property>
<property name="flushMode">
<bean id="org.springframework.orm.hibernate3.HibernateAccessor.FLUSH_AUTO" class="org.springframework.beans.factory.configFieldRetrievingFactoryBean" />
</property>
</bean>  

and add the bean to the list of interceptors by replacing :



<property name="interceptors">
<ref bean="localeChangeInterceptor" />
</property>
with




<property name="interceptors">
<list>
<ref bean="localeChangeInterceptor" />
<ref bean="openSessionInViewInterceptor"/>
</list>
</property>

The above directive will bind a Hibernate Session to the thread for the entire processing of the request by using OpenSessionInViewInterceptor

Monday, June 13, 2011

Insert values from one table to another in MySQL

Problem:
The problem was to insert values from a MySQL table into another one. In simple terms, For every 'id' in 'table_1', insert into 'table_2' the values of all the ids, name

Technology: SQL

Solution: Use INSERT INTO with SELECT

INSERT INTO table_2(id,name)
SELECT id,name FROM table_1;
More complex usage -> if you want to assign a constant value in one of the columns (here it is name) and 'id' from table_1, do like this
INSERT INTO table_2(id,name) 
SELECT id,'name' FROM table_1; 
If you want to match from two tables and store into the common table

INSERT INTO table_2(id,name,phonenum)
SELECT a.id,a.name,b.phonenum FROM table_1 a inner join table_3 b WHERE a.id=b.id;