Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Hibernate LazyInitializationException in web application Struts as MVC, Spring as IOC and Hibernate as ORM layer

134 views
Skip to first unread message

Amit Jain

unread,
Apr 24, 2009, 1:33:26 AM4/24/09
to
I am attempting to create a web application using Struts MVC, Spring
IOC and with Hibernate as its ORM layer.

Exception raised when I try to get memberVO object. Problem with
Hibernate Lazy initialization.

stack trace:
-------------------------------------------------------------
javax.servlet.ServletException:
org.hibernate.LazyInitializationException: failed to lazily initialize
a collection of role: com.yashbinary.crtracker.vo.MemberVO.apsses, no
session or session was closed
org.apache.struts.action.RequestProcessor.processException
(RequestProcessor.java:535)
org.apache.struts.action.RequestProcessor.processActionPerform
(RequestProcessor.java:433)

com.yashbinary.crtracker.struts.controller.XRequestProcessor.processActionPerform
(XRequestProcessor.java:45)
org.apache.struts.action.RequestProcessor.process
(RequestProcessor.java:236)
com.yashbinary.crtracker.struts.controller.XRequestProcessor.process
(XRequestProcessor.java:32)
org.apache.struts.action.ActionServlet.process(ActionServlet.java:
1196)
org.apache.struts.action.ActionServlet.doPost(ActionServlet.java:432)
javax.servlet.http.HttpServlet.service(HttpServlet.java:637)
javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
org.netbeans.modules.web.monitor.server.MonitorFilter.doFilter
(MonitorFilter.java:390)

org.hibernate.LazyInitializationException: failed to lazily initialize
a collection of role: com.yashbinary.crtracker.vo.MemberVO.apsses, no
session or session was closed
at
org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationException
(AbstractPersistentCollection.java:358)
at
org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationExceptionIfNotConnected
(AbstractPersistentCollection.java:350)
at
org.hibernate.collection.AbstractPersistentCollection.initialize
(AbstractPersistentCollection.java:343)
at org.hibernate.collection.AbstractPersistentCollection.read
(AbstractPersistentCollection.java:86)
at org.hibernate.collection.PersistentSet.hashCode
(PersistentSet.java:411)
at java.util.HashMap.containsKey(HashMap.java:377)
at java.util.HashSet.contains(HashSet.java:182)
at
org.apache.commons.lang.builder.ReflectionToStringBuilder.isRegistered
(ReflectionToStringBuilder.java:133)
at
org.apache.commons.lang.builder.ReflectionToStringBuilder.appendFieldsIn
(ReflectionToStringBuilder.java:629)
at
org.apache.commons.lang.builder.ReflectionToStringBuilder.toString
(ReflectionToStringBuilder.java:789)
at
org.apache.commons.lang.builder.ReflectionToStringBuilder.toString
(ReflectionToStringBuilder.java:355)
at
org.apache.commons.lang.builder.ReflectionToStringBuilder.toString
(ReflectionToStringBuilder.java:173)
at com.yashbinary.crtracker.common.ValueObject.toString
(ValueObject.java:23)
at java.lang.String.valueOf(String.java:2615)
at java.lang.StringBuilder.append(StringBuilder.java:116)
at com.yashbinary.crtracker.struts.login.LoginAction.execute
(LoginAction.java:52)
at org.springframework.web.struts.DelegatingActionProxy.execute
(DelegatingActionProxy.java:106)
at
org.apache.struts.action.RequestProcessor.processActionPerform
(RequestProcessor.java:431)
at
com.yashbinary.crtracker.struts.controller.XRequestProcessor.processActionPerform
(XRequestProcessor.java:45)
at org.apache.struts.action.RequestProcessor.process
(RequestProcessor.java:236)
at
com.yashbinary.crtracker.struts.controller.XRequestProcessor.process
(XRequestProcessor.java:32)
at org.apache.struts.action.ActionServlet.process
(ActionServlet.java:1196)
at org.apache.struts.action.ActionServlet.doPost
(ActionServlet.java:432)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:
637)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:
717)
at
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter
(ApplicationFilterChain.java:290)
at org.apache.catalina.core.ApplicationFilterChain.doFilter
(ApplicationFilterChain.java:206)
at
org.netbeans.modules.web.monitor.server.MonitorFilter.doFilter
(MonitorFilter.java:390)
at
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter
(ApplicationFilterChain.java:235)
at org.apache.catalina.core.ApplicationFilterChain.doFilter
(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke
(StandardWrapperValve.java:233)
at org.apache.catalina.core.StandardContextValve.invoke
(StandardContextValve.java:191)
at org.apache.catalina.core.StandardHostValve.invoke
(StandardHostValve.java:128)
at org.apache.catalina.valves.ErrorReportValve.invoke
(ErrorReportValve.java:102)
at org.apache.catalina.core.StandardEngineValve.invoke
(StandardEngineValve.java:109)
at org.apache.catalina.connector.CoyoteAdapter.service
(CoyoteAdapter.java:286)
at org.apache.coyote.http11.Http11Processor.process
(Http11Processor.java:845)
at org.apache.coyote.http11.Http11Protocol
$Http11ConnectionHandler.process(Http11Protocol.java:583)
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run
(JIoEndpoint.java:447)
at java.lang.Thread.run(Thread.java:595)
-----------------------------------------------------------------------------------

Here is a code:
---------------------------------------

hibernate.cfg.xml
---------------------------------------
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate
Configuration DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-
configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property
name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<property
name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</
property>
<property name="hibernate.connection.url">jdbc:mysql://localhost:
3306/crtracker</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">root</property>
<mapping resource="com/yashbinary/crtracker/vo/h_mapping/
Apss.hbm.xml"/>
<mapping resource="com/yashbinary/crtracker/vo/h_mapping/
Member.hbm.xml"/>
</session-factory>
</hibernate-configuration>

Member.hbm.xml
--------------------------------
<hibernate-mapping>
<class name="com.yashbinary.crtracker.vo.MemberVO" table="member"
catalog="crtracker">
<id name="empId" type="int">
<column name="emp_id" />
<generator class="assigned" />
</id>
<property name="firstName" type="string">
<column name="first_name" length="50" />
</property>
<property name="lastName" type="string">
<column name="last_name" length="50" />
</property>
<property name="emailId" type="string">
<column name="email_id" length="20" />
</property>
<property name="password" type="string">
<column name="password" length="10" />
</property>
<set name="apsses" inverse="true">
<key>
<column name="owner" not-null="true" unique="true" />
</key>
<one-to-many class="com.yashbinary.crtracker.vo.ApssVO" />
</set>
</class>
</hibernate-mapping>

applicationContext.xml
-------------------------------------------------
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource"><ref local="dataSource"/></property>
<property name="mappingResources">
<list> <value>com/yashbinary/crtracker/vo/h_mapping/
Member.hbm.xml</value>
<value>com/yashbinary/crtracker/vo/h_mapping/
Apss.hbm.xml</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">${hibernate.dialect}</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.hbm2ddl.auto">create</prop>
</props>
</property>
</bean>

MemberVO.java
-----------------------------------------
package com.yashbinary.crtracker.vo;
import com.yashbinary.crtracker.common.ValueObject;
import java.util.HashSet;
import java.util.Set;
public class MemberVO extends ValueObject implements
java.io.Serializable {
private int empId;
private String firstName;
private String lastName;
private String emailId;
private String password;
private Set<ApssVO> apsses = new HashSet<ApssVO>(0);
public MemberVO() {
}
public MemberVO(int empId) {
this.empId = empId;
}
public MemberVO(int empId, String firstName, String lastName, String
emailId, String password, Set<ApssVO> apsses) {
this.empId = empId;
this.firstName = firstName;
this.lastName = lastName;
this.emailId = emailId;
this.password = password;
this.apsses = apsses;
}

// setter n getter for empId, firstName, lastName, emailId,
password

public Set<ApssVO> getApsses() {
return this.apsses;
}
public void setApsses(Set<ApssVO> apsses) {
this.apsses = apsses;
}
}

MemberDAO.java
----------------------------------
package com.yashbinary.crtracker.member.dao;
import org.hibernate.Criteria;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.criterion.Restrictions;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
public class MemberDAO extends HibernateDaoSupport implements
DataAccessObject {

public ValueObject findByCriteria(MemberVO memberVO) throws
DataAccessException{
log.debug("findByCriteria() start");
Session session = null;
Criteria criteria = null;
MemberVO returnVO = null;
try{
session = getHibernateTemplate().getSessionFactory
().openSession();
criteria = session.createCriteria(MemberVO.class);

criteria.add(Restrictions.eq("empId", memberVO.getEmpId
() ) );
criteria.add(Restrictions.eq("password",
memberVO.getPassword() ) );

//returnVO = (MemberVO) criteria.uniqueResult();
List returnVOList = criteria.list();
if(returnVOList!=null){
returnVO = (MemberVO)returnVOList.get(0);
}
}catch(HibernateException e){
log.error("HibernateException thrown in
MemberDAO.findByCriteria()", e);
}catch(ServiceLocatorException e){
log.error("ServiceLocatorException thrown in
MemberDAO.findByCriteria()", e);
}finally{
if(session!=null)
session.close();
}
log.debug("findByCriteria() end");
return returnVO;
}
}

MemberManagerBD.java
-----------------------------------------------
public class MemberManagerBD {
public MemberVO authenticate(String empId, String password) throws
ApplicationException{
MemberDAO memberDAO = getMemberDAO();
MemberVO memberVO = (MemberVO) memberDAO.findByCriteria
(memberVO);
return memberVO;
}

LoginAction.java
---------------------------------------
public class LoginAction extends org.apache.struts.action.Action {
public ActionForward execute(){
MemberManagerBD memManagerBD = getMemberMangerBD();
memberVO = memManagerBD.authenticate(((LoginForm)form).getEmpId(),
((LoginForm)form).getPassword()
);
}
}

Thanks in advance for your help

Amit Jain

Perfect.C

unread,
Apr 24, 2009, 2:45:37 AM4/24/09
to
try OpenSessionInViewFilter supplied by Springframework.

Amit Jain

unread,
Apr 24, 2009, 5:50:02 AM4/24/09
to
On Apr 24, 11:45 am, "Perfect.C" <tendergh...@gmail.com> wrote:
> try OpenSessionInViewFilter supplied by Springframework.

Thanks for you reply,

I checked expection and found that it cause because of overridden
toString() method of class abstact ValuObject.java

public abstract class ValueObject {

/** Creates a new instance of ValueObject */
public ValueObject() {
}

public String toString() {
return ReflectionToStringBuilder.toString(this);
}
}
ValueObject's toString() method is the cause of exception. But I don't
understand why this toString method through exception.
I have taken reference of example mentioned in book pro-apache-struts
with ajax by Apress.

Once again thanks alot for your reply...

Amit Jain

Jean-Baptiste Nizet

unread,
Apr 24, 2009, 11:44:57 AM4/24/09
to
Amit Jain a écrit :

> On Apr 24, 11:45 am, "Perfect.C" <tendergh...@gmail.com> wrote:
>> try OpenSessionInViewFilter supplied by Springframework.
>
> Thanks for you reply,
>
> I checked expection and found that it cause because of overridden
> toString() method of class abstact ValuObject.java
>
> public abstract class ValueObject {
>
> /** Creates a new instance of ValueObject */
> public ValueObject() {
> }
>
> public String toString() {
> return ReflectionToStringBuilder.toString(this);
> }
> }
> ValueObject's toString() method is the cause of exception. But I don't
> understand why this toString method through exception.

You need to understand how Hibernate handles XXX-to-many lazy
relationships. Hibernate doesn't load all the objects of the collection
directly. Instead, when you invoke a method of the collection for the
first time, it executes an additional database query to load all the
objects of the collection. In order for this query to work, the object
must be associated to an open session. I suspect that you're doing the
following:
1. open a session
2. load your value object using the session
3. close the session
4. call the toString() method on the value object

Since your toString() method probably invokes all the getters it finds
on the value object and certainly invoke toString() on the result,
Hibernate tries to load the objects in the collection, but your session
is closed. So you have two solutions:

1. make sure you don't access non-loaded objects or collections of
detached objects
2. make sure the session stays open until you're done with the object,
in other words, don't use detached objects.

Anyway, such an implementation of toString() will cause problems with
detached hibernate objects.

JB.

Lew

unread,
Apr 24, 2009, 7:58:08 PM4/24/09
to
Jean-Baptiste Nizet wrote:
> You need to understand how Hibernate handles XXX-to-many lazy
> relationships. Hibernate doesn't load all the objects of the collection
> directly. Instead, when you invoke a method of the collection for the
> first time, it executes an additional database query to load all the
> objects of the collection. In order for this query to work, the object
> must be associated to an open session. I suspect that you're doing the
> following:
> 1. open a session
> 2. load your value object using the session
> 3. close the session
> 4. call the toString() method on the value object
>
> Since your toString() method probably invokes all the getters it finds
> on the value object and certainly invoke toString() on the result,
> Hibernate tries to load the objects in the collection, but your session
> is closed. So you have two solutions:
>
> 1. make sure you don't access non-loaded objects or collections of
> detached objects
> 2. make sure the session stays open until you're done with the object,
> in other words, don't use detached objects.
>
> Anyway, such an implementation of toString() will cause problems with
> detached hibernate objects.

Even absent the lazy-load behavior (also fixable by eager loading, BTW), that
may not be the most desirable implementation of 'toString()'. Does a list of
all the associated objects really belong in the 'toString()' representation?
What if they have a many-to-one relationship back to the parent object and
their 'toString()' tries to list it? You'd have a cycle that you can't break.

--
Lew

Amit Jain

unread,
Apr 25, 2009, 2:52:28 AM4/25/09
to
Thanks to All for there valuable inputs.

Things are very clear from analysis. I remove the method toString()
from ValueObject abstract class. And Hibernate exeption related to
Lazy initialization is removed.

But I don't know what will be the impact on the flow by removal of
toString() method.

Thanks & Regards,
Amit Jain

Lew

unread,
Apr 25, 2009, 9:52:55 AM4/25/09
to
Amit Jain wrote:
> But I don't know what will be the impact on the flow by removal of
> toString() method.

What was its purpose in the flow?

How did you implement it in the abstract class?

Bear in mind that you didn't remove the 'toString()' method, only the specific
implementation.

Could you implement it differently?

What do you want it to do for you?

--
Lew

Amit Jain

unread,
Apr 27, 2009, 6:27:29 AM4/27/09
to
The Value Objects are used in the application: MemberVO, apssVO. All
of these classes extend an abstract class called ValueObject. (The
Value Object pattern can be implemented in a number of ways.) The code
for the ValueObject class is shown here:
package com.yashbinary.crtracker.common;
import org.apache.commons.lang.builder.ReflectionToStringBuilder;

public abstract class ValueObject {
/** Creates a new instance of ValueObject */
public ValueObject() {
}
public String toString() {
return ReflectionToStringBuilder.toString(this);
}
}

The ValueObject class serves as a good base class for putting methods
that are going to be
shared across all Value Objects in the application. we needed to dump
the contents of a JavaBean. Rather than writing own method to do this,
we used the ReflectionToStringBuilder class from the Jakarta Commons
lang project. The Commons lang project provides several “helper”
utilities for carrying out most low-level tasks related to the core
java.lang classes. The ReflectionToStringBuilder classes use Java
reflection to build a string containing all of the properties within a
class. By overriding the toString() method on the base ValueObjects
and using the
ReflectionToStringBuilder class, in three lines of code we were able
to have a consistent
mechanism for dumping the contents of a JavaBean. The preceding
example only shows a
very simple use of the ReflectionToStringBuilder class.
In the application, the ValueObject interface is used as a marker
interface to
indicate that the class is a Value Object. This interface has no
method signatures and provides
a generic type for passing data in and out of a DAO. By passing only
ValueObjects in the
DataAccessObject interface, you can guarantee that every DAO in the
application
supports a base set of CRUD functionality. It is the responsibility of
the DAO to cast the
ValueObject to the type it is expecting.

I am taking reference from book "pro-apache-struts-with-ajax"
publisher Apress.

0 new messages