Hello,
I am new to Hibernate and I'm sorry, if this has been asked before - but I did search the forum but I still can't get my
problem fixed.
First of all, I'm running Hibernate in a Web Application using the Spring framework which handles my Hibernate SessionFactory
and Transaction Management.
applicationContext.xml (Spring)
Code:
<beans>
...
<!-- dataSource -->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName"><value>${jdbc.driverClassName}</value></property>
<property name="url"><value>${jdbc.url}</value></property>
<property name="username"><value>${jdbc.username}</value></property>
<property name="password"><value>${jdbc.password}</value></property>
</bean>
<!-- Hibernate SessionFactory -->
<bean id="sessionFactory" class="org.springframework.orm.hibernate.LocalSessionFactoryBean">
<property name="dataSource"><ref local="dataSource"/></property>
<property name="mappingDirectoryLocations">
<list>
<value>classpath:/org/mmo/model/hbm</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">${jdbc.dialect}</prop>
<prop key="hibernate.show_sql">true</prop>
</props>
</property>
</bean>
<!-- Transaction manager for a single Hibernate SessionFactory (alternative to JTA) -->
<bean id="transactionManager" class="org.springframework.orm.hibernate.HibernateTransactionManager">
<property name="sessionFactory"><ref local="sessionFactory"/></property>
</bean>
...
<!-- Daos -->
...
</beans>
In my model, I'm mapping a bi-directional association using this notation:
Code:
<class name="org.mmo.model.SchuelerMatura">
...
<set name="fachklausuren" inverse="true" lazy ="true" cascade="all" >
<key column="Schueler_MaturaID" />
<one-to-many class="org.mmo.model.SchuelerFachklausur"/>
</set>
...
</class>
respectively
Code:
<class name="org.mmo.model.SchuelerFachklausur">
...
<!-- bi-directional many-to-one association to SchuelerMatura -->
<many-to-one name="schuelerMatura" class="org.mmo.model.SchuelerMatura" column="Schueler_MaturaID"/>
...
</class>
Now, when I load a collection of SchuelerMatura-entities using my Dao-Class
Code:
public Collection getSchuelerMaturaByClassAgeGroupId(String classAgeGroupId) {
Collection c = getHibernateTemplate().find("select sm from SchuelerMatura sm , " +
"Schueler s, " +
"SchuelerKlasse k " +
"where sm.schueler.schuelerId = s.schuelerId and " +
"s.schuelerId = k.schueler.schuelerId and " +
"k.klasseJahrgang.klasseJahrgangId = ? and " +
"sm.berechtigt = '1' " +
"order by k.katalogNr", classAgeGroupId);
/*Collection c = getHibernateTemplate().find("select sm from SchuelerMatura sm , " +
"Schueler s, " +
"SchuelerKlasse k inner join fetch sm.fachklausuren " +
"where sm.schueler.schuelerId = s.schuelerId and " +
"s.schuelerId = k.schueler.schuelerId and " +
"k.klasseJahrgang.klasseJahrgangId = ? and " +
"sm.berechtigt = '1' " +
"order by k.katalogNr", classAgeGroupId); */
try {
for (Iterator it = c.iterator(); it.hasNext(); ) {
SchuelerMatura sm = (SchuelerMatura) it.next();
// trying to initialize the lazy collection (set)
Hibernate.initialize(sm.getFachklausuren());
}
} catch(HibernateException hex) {
log.error(hex.getMessage());
}
return c;
}
I get either a LazyInitializationException like this
ERROR - LazyInitializationException.<init>(25) | cannot access loading collection
net.sf.hibernate.LazyInitializationException: cannot access loading collection
at net.sf.hibernate.collection.PersistentCollection.initialize(PersistentCollection.java:191)
at net.sf.hibernate.collection.PersistentCollection.read(PersistentCollection.java:71)
at net.sf.hibernate.collection.Set.hashCode(Set.java:383)
at org.apache.commons.lang.builder.HashCodeBuilder.append(HashCodeBuilder.java:392)
at org.apache.commons.lang.builder.HashCodeBuilder.reflectionAppend(HashCodeBuilder.java:353)
at org.apache.commons.lang.builder.HashCodeBuilder.reflectionHashCode(HashCodeBuilder.java:327)
at org.apache.commons.lang.builder.HashCodeBuilder.reflectionHashCode(HashCodeBuilder.java:194)
at org.mmo.model.BaseObject.hashCode(BaseObject.java:40)
at org.apache.commons.lang.builder.HashCodeBuilder.append(HashCodeBuilder.java:392)
at org.apache.commons.lang.builder.HashCodeBuilder.reflectionAppend(HashCodeBuilder.java:353)
at org.apache.commons.lang.builder.HashCodeBuilder.reflectionHashCode(HashCodeBuilder.java:327)
at org.apache.commons.lang.builder.HashCodeBuilder.reflectionHashCode(HashCodeBuilder.java:194)
at org.mmo.model.BaseObject.hashCode(BaseObject.java:40)
at java.util.HashMap.hash(HashMap.java:257)
at java.util.HashMap.put(HashMap.java:375)
at java.util.HashSet.add(HashSet.java:188)
at java.util.AbstractCollection.addAll(AbstractCollection.java:315)
at net.sf.hibernate.collection.Set.endRead(Set.java:244)
at net.sf.hibernate.impl.SessionImpl.endLoadingCollections(SessionImpl.java:3078)
at net.sf.hibernate.impl.SessionImpl.endLoadingCollections(SessionImpl.java:3065)
at net.sf.hibernate.loader.Loader.doQuery(Loader.java:243)
at net.sf.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:133)
at net.sf.hibernate.loader.Loader.loadCollection(Loader.java:915)
at net.sf.hibernate.loader.Loader.loadCollection(Loader.java:890)
at net.sf.hibernate.loader.OneToManyLoader.initialize(OneToManyLoader.java:93)
at net.sf.hibernate.collection.AbstractCollectionPersister.initialize(AbstractCollectionPersister.java:284)
at net.sf.hibernate.impl.SessionImpl.initializeCollection(SessionImpl.java:3264)
at net.sf.hibernate.collection.PersistentCollection.forceInitialization(PersistentCollection.java:336)
at net.sf.hibernate.Hibernate.initialize(Hibernate.java:256)
at
org.mmo.dao.SchuelerMaturaDaoHibernateImpl.getSchuelerMaturaByClassAgeGroupId(SchuelerMaturaDaoHibernateImpl.java:46)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:324)
at org.springframework.aop.framework.AopProxyUtils.invokeJoinpointUsingReflection(AopProxyUtils.java:59)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:149)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:118)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:191)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:138)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:148)
at $Proxy0.getSchuelerMaturaByClassAgeGroupId(Unknown Source)
at org.mmo.web.FachklGenAction.execute(FachklGenAction.java:109)
at org.springframework.web.struts.DelegatingActionProxy.execute(DelegatingActionProxy.java:131)
at org.apache.struts.action.RequestProcessor.processActionPerform(RequestProcessor.java:449)
at org.apache.struts.action.RequestProcessor.process(RequestProcessor.java:264)
at org.apache.struts.action.ActionServlet.process(ActionServlet.java:1176)
at org.apache.struts.action.ActionServlet.doGet(ActionServlet.java:454)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:689)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:802)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:237)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:157)
at com.opensymphony.module.sitemesh.filter.PageFilter.parsePage(PageFilter.java:142)
at com.opensymphony.module.sitemesh.filter.PageFilter.doFilter(PageFilter.java:58)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:186)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:157)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:214)
at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:104)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:520)
at org.apache.catalina.core.StandardContextValve.invokeInternal(StandardContextValve.java:198)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:152)
at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:104)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:520)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:137)
at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:104)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:118)
at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:102)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:520)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:104)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:520)
at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:929)
at org.apache.coyote.tomcat5.CoyoteAdapter.service(CoyoteAdapter.java:160)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:799)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.processConnection(Http11Protocol.java:705)
at org.apache.tomcat.util.net.TcpWorkerThread.runIt(PoolTcpEndpoint.java:577)
at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:683)
at java.lang.Thread.run(Thread.java:536)
or - when I do not use Hibernate.initialize() to initialize my the collection - I get an LazyInitializationException telling
me that no Session was found, respectively the Session was closed.
After researching this issue, I thought Hibernate.initialize() provides the solution for this problem.
I've also seen approaches using HQL to fetch the collection data via inner joins like
Code:
getHibernateTemplate().find("select sm from SchuelerMatura sm , " +
"Schueler s, " +
"SchuelerKlasse k [b]inner join fetch sm.fachklausuren [/b]" +
"where sm.schueler.schuelerId = s.schuelerId and " +
"s.schuelerId = k.schueler.schuelerId and " +
"k.klasseJahrgang.klasseJahrgangId = ? and " +
"sm.berechtigt = '1' " +
"order by k.katalogNr", classAgeGroupId);
but it did not work for me, either.
One thing that might be of interest is, that I'm joining over 2 MS SQL catalogs and I therefore get a SQLWarning which I'm not
familiar with, I have to admit:
DEBUG - SessionImpl.afterTransactionCompletion(585) | transaction completion
DEBUG - JDBCTransaction.toggleAutoCommit(103) | re-enabling autocommit
DEBUG - SessionImpl.close(573) | closing session
DEBUG - SessionImpl.disconnect(3332) | disconnecting session
DEBUG - JDBCExceptionReporter.logWarnings(18) | SQL Warning
java.sql.SQLWarning: [Microsoft][SQLServer 2000 Driver for JDBC]Database changed to svs
at com.microsoft.jdbc.base.BaseWarnings.createSQLWarning(Unknown Source)
at com.microsoft.jdbc.base.BaseWarnings.get(Unknown Source)
at com.microsoft.jdbc.base.BaseConnection.getWarnings(Unknown Source)
at net.sf.hibernate.impl.BatcherImpl.closeConnection(BatcherImpl.java:289)
at net.sf.hibernate.impl.SessionImpl.disconnect(SessionImpl.java:3348)
at net.sf.hibernate.impl.SessionImpl.close(SessionImpl.java:576)
at org.springframework.orm.hibernate.SessionFactoryUtils.closeSessionIfNecessary(SessionFactoryUtils.java:350)
at org.springframework.orm.hibernate.HibernateTransactionManager.doCleanupAfterCompletion(HibernateTransactionManager.java:478)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.cleanupAfterCompletion(AbstractPlatformTransactionManager.java:510)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:351)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:211)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:138)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:148)
at $Proxy1.getClasses(Unknown Source)
at org.mmo.web.FachklGenAction.execute(FachklGenAction.java:99)
at org.springframework.web.struts.DelegatingActionProxy.execute(DelegatingActionProxy.java:131)
at org.apache.struts.action.RequestProcessor.processActionPerform(RequestProcessor.java:449)
at org.apache.struts.action.RequestProcessor.process(RequestProcessor.java:264)
at org.apache.struts.action.ActionServlet.process(ActionServlet.java:1176)
at org.apache.struts.action.ActionServlet.doGet(ActionServlet.java:454)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:689)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:802)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:237)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:157)
at com.opensymphony.module.sitemesh.filter.PageFilter.parsePage(PageFilter.java:142)
at com.opensymphony.module.sitemesh.filter.PageFilter.doFilter(PageFilter.java:58)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:186)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:157)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:214)
at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:104)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:520)
at org.apache.catalina.core.StandardContextValve.invokeInternal(StandardContextValve.java:198)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:152)
at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:104)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:520)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:137)
at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:104)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:118)
at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:102)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:520)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:104)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:520)
at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:929)
at org.apache.coyote.tomcat5.CoyoteAdapter.service(CoyoteAdapter.java:160)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:799)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.processConnection(Http11Protocol.java:705)
at org.apache.tomcat.util.net.TcpWorkerThread.runIt(PoolTcpEndpoint.java:577)
at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:683)
at java.lang.Thread.run(Thread.java:536)
WARN - JDBCExceptionReporter.logWarnings(20) | SQL Warning: 0, SQLState:
WARN - JDBCExceptionReporter.logWarnings(28) | [Microsoft][SQLServer 2000 Driver for JDBC]Database changed to svs
WARN - JDBCExceptionReporter.logWarnings(20) | SQL Warning: 5701, SQLState: 01000
WARN - JDBCExceptionReporter.logWarnings(28) | [Microsoft][SQLServer 2000 Driver for JDBC][SQLServer]Changed database context to 'svs'.
WARN - JDBCExceptionReporter.logWarnings(20) | SQL Warning: 0, SQLState:
WARN - JDBCExceptionReporter.logWarnings(28) | [Microsoft][SQLServer 2000 Driver for JDBC]Language changed to us_english
WARN - JDBCExceptionReporter.logWarnings(20) | SQL Warning: 5703, SQLState: 01000
WARN - JDBCExceptionReporter.logWarnings(28) | [Microsoft][SQLServer 2000 Driver for JDBC][SQLServer]Changed language setting to us_english.
DEBUG - SessionImpl.afterTransactionCompletion(585) | transaction completion
DEBUG - FachklGenAction.execute(103) | Maturaklassen:[org.mmo.model.svs.KlasseJahrgang@11bf785[klasseJahrgangId=170], org.mmo.model.svs.KlasseJahrgang@19c86c5[klasseJahrgangId=171], org.mmo.model.svs.KlasseJahrgang@1542cdc[klasseJahrgangId=173], org.mmo.model.svs.KlasseJahrgang@14d4313[klasseJahrgangId=172]]
DEBUG - SessionImpl.<init>(555) | opened session
This occurs after a collection is read by getHibernateTemplate().find("...") by one of my several Dao-Classes.
Due to using Spring I'm actually not managing the SessionFactory through a Singleton class like described in the Hibernate Documentation, and so I'm worried about how to keep the Session alive, when using the lazy collections - i thought using Hibernate.initialize() solves the problem nicely, but aparantly it doesn't - or did i make a major mistake applying it?
Hibernate version: 2.1.4
I'd greatly appreciate any help!
Thanks!