Je tente de créer une application web en utilisant Spring MVC, avec Hibernate comme couche ORM. Cependant, en raison de mon inexpérience avec les deux cadres, je me bats.Pourquoi une exception Hibernate LazyInitializationException s'affiche-t-elle dans cette application Web Spring MVC lorsque les données s'affichent correctement?
Le code suivant affichera correctement tous les enregistrements que je recherche mais jette toujours une trace de pile dans mes journaux. J'ai du mal à trouver une documentation complète concernant l'intégration d'Hibernate et de SpringMVC (j'ai regardé sur springsource.org et lu divers articles sur l'interweb). Quelqu'un pourrait-il souligner ce que je pourrais faire mal ici?
S'il vous plaît noter que j'ai passé un peu d'essayer de traquer les réponses sur Internet pour cela, y compris en regardant this SO question. Ce qui n'était malheureusement pas une aide.
Je devrais également noter que la partie ORM de cette application a été utilisée et testée dans une application Java autonome sans problèmes. Je crois donc que l'intégration de Spring MVC et d'Hibernate est à l'origine du problème.
Voici la trace de la pile (tronquée) avec le fameux problème d'initialisation paresseux;
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)
.....
Voici un code de mon contrôleur de page 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;
}
Qui est employé sur la page Web en utilisant cet affichage 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>
Remarque: Que j'ai ajouté report.searchRule.name pour tester si je pouvais obtenir les objets dans l'objet de rapport. Il affiche bien.
Et dans mon 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>
Voici les mappages ORM, juste au cas où;
Le hibernate.cfg.xml (comme l'avait demandé)
<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>
De 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 post la mappage pour les rapports aussi –
Ajouté hibernate.cfg.xml, qui contient mes mappages. –
Pouvez-vous afficher le fichier Report.hbm.xml? –