-
FEATURED COMPONENTS
First time here? Check out the FAQ!
hi all,
My web app is ZK + spring(as service layer) +hibernate(as DAO)
I use spring to manage SessionFactory, and all DAO class inherit from Spring's HibernateDAOSupport.
and some of mapping are lazy loading (lazy="true").
Applying configuration according to
Hibernate + ZK
http://www.zkoss.org/smalltalks/hibernatezk/hibernatezk.dsp
Hibernate + Spring + ZK
http://www.zkoss.org/smalltalks/hibnsprn/hibn_sprn_zk.html.
I apply zk 3 listener
zk.xml
<!-- Configure the Hibernate SessionFactory Lifecycle. -->
<listener>
<description>Hibernate SessionFactory Lifecycle</description>
<listener-class>org.zkoss.zkplus.hibernate.HibernateSessionFactoryListener</listener-class>
</listener>
<!-- Configure the Hibernate "Open Session In View" Session Lifecycle -->
<listener>
<description>Hibernate "Open Session In View" Session Lifecycle</description>
<listener-class>org.zkoss.zkplus.hibernate.OpenSessionInViewListener</listener-class>
</listener>
<!-- Hibernate thread session context handler -->
<listener>
<description>Hibernate thread session context handler</description>
<listener-class>
org.zkoss.zkplus.hibernate.HibernateSessionContextListener
</listener-class>
</listener>
applicationContext.xml
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"
destroy-method="close">
<property name="dataSource" ref="dataSource"/>
<property name="mappingResources">
<list>
...
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.current_session_context_class">thread</prop>
<!-- Hibernate's transaction factory -->
<prop key="transaction.factory_class">org.hibernate.transaction.JDBCTransactionFactory</prop>
</props>
</property>
emp.zul
<window title="EmployeeService" border="normal" apply="${employeeComposer}">
<listbox id="employeeList" model="@{employeeComposer.employees}" selectedItem="@{employeeComposer.selectedEmployee}">
<listhead>
<listheader label="name"></listheader>
</listhead>
<listitem self="@{each=e}">
<listcell label="@{e.chineseName}"></listcell>
</listitem>
</listbox>
<listbox id="familyMemberList" model="@{employeeComposer.selectedEmployee.familys}">
<listhead>
<listheader label="family member name"></listheader>
</listhead>
<listitem self="@{each=f}">
<listcell label="@{f.name}"></listcell>
</listitem>
</listbox>
<textbox value="@{employeeComposer.selectedEmployee.chineseName}"></textbox>
<button id="save" label="save" forward="onSave"/>
</window>
when user click one row of employee listbox, it go to access employee's family. familys is a set which is lazy loading.
How do I get Session in my DAO class with ZK and lazy loading?
1. use getHibernateTemplate()
ex:
public void saveOrUpdate(Object obj) {
getHibernateTemplate().saveOrUpdate(obj);
}
I always got " session is closed" when ZK UI tries to access lazy loading set.
ERROR org.hibernate.LazyInitializationException - failed to lazily initialize a collection of role: ..., no session or session was closed
org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: ..., no session or session was closed
at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:380)
at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationExceptionIfNotConnected(AbstractPersistentCollection.java:372)
at org.hibernate.collection.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:365)
at org.hibernate.collection.AbstractPersistentCollection.read(AbstractPersistentCollection.java:108)
at org.hibernate.collection.PersistentSet.hashCode(PersistentSet.java:434)
at java.util.HashMap.get(Unknown Source)
at org.zkoss.zkplus.databind.DataBinder.getBeanSameNodes(DataBinder.java:946)
at org.zkoss.zkplus.databind.DataBinder.registerBeanNode(DataBinder.java:1143)
2. use HibernateUtil.currentSession()
got " session is closed" when ZK UI tries to access lazy loading set.
ERROR org.hibernate.LazyInitializationException - failed to lazily initialize a collection of role: ..., no session or session was closed
org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: ..., no session or session was closed
at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:380)
at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationExceptionIfNotConnected(AbstractPersistentCollection.java:372)
at org.hibernate.collection.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:365)
at org.hibernate.collection.AbstractPersistentCollection.read(AbstractPersistentCollection.java:108)
at org.hibernate.collection.PersistentSet.hashCode(PersistentSet.java:434)
at java.util.HashMap.get(Unknown Source)
at org.zkoss.zkplus.databind.DataBinder.getBeanSameNodes(DataBinder.java:946)
at org.zkoss.zkplus.databind.DataBinder.registerBeanNode(DataBinder.java:1143)
3. every time use Spring's HibernateDaoSupport getSession()
in 2nd time I call getSession().saveOrUpdate(), it show
Illegal attempt to associate a collection with two open sessions
I must use merge()
It seems the Session created by HibernateUtil.currentSession() is not binding to the lazy loaded Collection and can't be used by Hibernate to initialize lazy collection.
Could someone who use the similar architecture sharing some idea? How to get session is correct in this case?
or should I change my architecture?
Notice: I hope I can keep lazy="true"
Have a look on this thread.
Seems the ThreadLocal synchronisation is missing in your configuration.
manager.refresh(model);
model = manager.findByModel(model);
((Gridbox) objectWindow.getFellow("gridSubBrazil")).updateFromModel();
Asked: 2009-12-02 04:16:34 +0800
Seen: 2,210 times
Last updated: May 27 '16