Sto tentando di creare un'applicazione Web utilizzando Spring MVC, con Hibernate come layer ORM. Tuttavia, a causa della mia inesperienza con entrambe le strutture, sto lottando.Perché ricevo Hibernate LazyInitializationException in questa applicazione Web MVC di Spring quando i dati vengono visualizzati correttamente?
Il seguente codice visualizzerà correttamente tutti i record che sto cercando, ma getterò comunque una traccia di stack nei miei registri. Ho difficoltà a trovare una documentazione approfondita sull'integrazione di Hibernate e SpringMVC (ho cercato su springsource.org e ho letto vari articoli sull'interweb). Qualcuno potrebbe far notare cosa potrei fare di sbagliato qui?
Si prega di notare che ho speso alcuni cercando di rintracciare le risposte su Internet per questo, tra cui guardando domanda this SO. Che purtroppo non è stato d'aiuto.
Devo anche notare che la parte ORM di questa applicazione è stata utilizzata e testata in un'applicazione Java autonoma senza problemi. Quindi credo che l'integrazione di Spring MVC e Hibernate stia causando il problema.
Ecco la traccia dello stack (troncata) con il famoso problema di inizializzazione pigro;
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)
.....
Ecco un codice dal mio controller di pagina web;
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;
}
Quale viene utilizzato sulla pagina Web utilizzando questo 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>
Nota: che ho aggiunto report.searchRule.name per verificare se ho potuto ottenere presso gli oggetti all'interno dell'oggetto report. Visualizza bene.
E nel mio 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>
Ecco i mapping ORM, per ogni evenienza;
Il hibernate.cfg.xml (come richiesto)
<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>
Da 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>
pls inviare la mappatura anche per report –
Aggiunto hibernate.cfg.xml, che contiene i miei mapping. –
Puoi mostrare il file Report.hbm.xml? –