I am attempting to create a web application using Spring MVC, with Hibernate as its ORM layer. However, due to my inexperience with both frameworks I'm struggling.
The following code will properly display all the records I am looking for but still throw a stack trace into my logs. I'm having trouble finding thorough documentation concerning integrating Hibernate and SpringMVC (I've looked on springsource.org and read various articles on the interweb). Could anyone point out what I could be doing wrong here?
Please note that I have spent a few trying to track down answers on the internet for this, including looking at this SO question. Which was unfortunately no help.
I should also note that the ORM part of this application has been used and tested in a stand alone Java application without problems. So I believe the integration of Spring MVC and Hibernate is causing the issue.
Here is the stack trace (truncated) with the famous lazy initialization issue;
2009-03-10 12:14:50,353 [http-8084-6] ERROR org.hibernate.LazyInitializationException.<init>(LazyInitializationException.java:19) - could not initialize proxy - no Session
org.hibernate.LazyInitializationException: could not initialize proxy - no Session
at org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializer.java:57)
at org.hibernate.proxy.AbstractLazyInitializer.getImplementation(AbstractLazyInitializer.java:111)
at org.hibernate.proxy.pojo.cglib.CGLIBLazyInitializer.invoke(CGLIBLazyInitializer.java:150)
at com.generic.orm.generated.SearchRule$$EnhancerByCGLIB$$92abaed6.toString(<generated>)
at java.lang.String.valueOf(String.java:2827)
at java.lang.StringBuffer.append(StringBuffer.java:219)
at org.apache.commons.lang.builder.ToStringStyle.appendDetail(ToStringStyle.java:578)
at org.apache.commons.lang.builder.ToStringStyle.appendInternal(ToStringStyle.java:542)
at org.apache.commons.lang.builder.ToStringStyle.append(ToStringStyle.java:428)
at org.apache.commons.lang.builder.ToStringBuilder.append(ToStringBuilder.java:840)
at org.apache.commons.lang.builder.ReflectionToStringBuilder.appendFieldsIn(ReflectionToStringBuilder.java:606)
.....
Here is a code from my web page controller;
private List<Report> getReports() {
Session session = HibernateUtil.getSessionFactory().getCurrentSession();
session.beginTransaction();
List<Report> reports = session.createCriteria(Report.class).list();
Hibernate.initialize(reports);
session.getTransaction().commit();
return reports;
}
Which is employed on the web page using this display html;
<table border="1">
<c:forEach items="${model.reports}" var="report">
<tr>
<td><c:out value="${report.id}"/></td>
<td><c:out value="${report.username}"/></td>
<td><c:out value="${report.thresholdMet}"/></td>
<td><c:out value="${report.results}"/></td>
<td><c:out value="${report.searchRule.name}"/></td>
<td><c:out value="${report.uuid}"/></td>
</tr>
</c:forEach>
</table>
Note: That I added report.searchRule.name to test if I could get at the objects within the report object. It displays fine.
And in my applicationContext.xml;
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="configLocation">
<value>classpath:hibernate.cfg.xml</value>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">${hibernate.dialect}</prop>
</props>
</property>
</bean>
Here are the ORM mappings, just in case;
The hibernate.cfg.xml (as requested)
<hibernate-configuration>
<session-factory>
<property name="hibernate.connection.driver_class">com.microsoft.sqlserver.jdbc.SQLServerDriver</property>
<property name="hibernate.connection.url">jdbc:sqlserver://<removed></property>
<property name="hibernate.connection.username"><removed></property>
<property name="hibernate.connection.password"><removed></property>
<property name="hibernate.current_session_context_class">thread</property>
<property name="hibernate.show_sql">false</property>
<mapping resource="com/generic/orm/generated/Report.hbm.xml"/>
<mapping resource="com/generic/orm/generated/FieldRule.hbm.xml"/>
<mapping resource="com/generic/orm/generated/Reconciliation.hbm.xml"/>
<mapping resource="com/generic/orm/generated/SearchRule.hbm.xml"/>
<mapping resource="com/generic/orm/generated/IndexTemplate.hbm.xml"/>
<mapping resource="com/generic/orm/generated/Field.hbm.xml"/>
<mapping resource="com/generic/orm/generated/ErrorCode.hbm.xml"/>
</session-factory>
</hibernate-configuration>
From report.hbm.xml
<hibernate-mapping>
<class name="com.generic.orm.generated.Report" table="Report" schema="dbo" catalog="CoolRecon">
<id name="id" type="int">
<column name="ID" />
<generator class="native" />
</id>
<timestamp name="timeStamp" column="TimeStamp" />
<many-to-one name="searchRule" class="com.generic.orm.generated.SearchRule" fetch="select">
<column name="SearchRuleName" length="50" not-null="true" />
</many-to-one>
<many-to-one name="errorCode" class="com.generic.orm.generated.ErrorCode" fetch="select">
<column name="ErrorCodeId" />
</many-to-one>
<many-to-one name="reconciliation" class="com.generic.orm.generated.Reconciliation" fetch="select">
<column name="ReconciliationName" length="100" />
</many-to-one>
<property name="username" type="string">
<column name="Username" length="50" />
</property>
<property name="supersheetDate" type="timestamp">
<column name="SupersheetDate" length="23" not-null="true" />
</property>
<property name="milliSecondsTaken" type="long">
<column name="MilliSecondsTaken" not-null="true" />
</property>
<property name="thresholdMet" type="boolean">
<column name="ThresholdMet" not-null="true" />
</property>
<property name="results" type="int">
<column name="Results" not-null="true" />
</property>
<property name="exception" type="string">
<column name="Exception" length="750" />
</property>
<property name="uuid" type="string">
<column name="UUID" length="36" not-null="true" />
</property>
</class>
</hibernate-mapping>