0

how to get session in DAO

asked 2009-12-02 04:16:34 +0800

hawk gravatar image hawk
3250 1 5
http://hawkphoenix.blogsp... ZK Team

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"

delete flag offensive retag edit

2 Replies

Sort by ยป oldest newest

answered 2009-12-02 08:07:54 +0800

terrytornado gravatar image terrytornado flag of Germany
9393 3 7 16
http://www.oxitec.de/

Have a look on this thread.
Seems the ThreadLocal synchronisation is missing in your configuration.

link publish delete flag offensive edit

answered 2012-05-18 11:40:43 +0800

alfredogaspar gravatar image alfredogaspar
3

manager.refresh(model);
model = manager.findByModel(model);
((Gridbox) objectWindow.getFellow("gridSubBrazil")).updateFromModel();

link publish delete flag offensive edit
Your reply
Please start posting your answer anonymously - your answer will be saved within the current session and published after you log in or create a new account. Please try to give a substantial answer, for discussions, please use comments and please do remember to vote (after you log in)!

[hide preview]

Question tools

Follow

RSS

Stats

Asked: 2009-12-02 04:16:34 +0800

Seen: 2,210 times

Last updated: May 27 '16

Support Options
  • Email Support
  • Training
  • Consulting
  • Outsourcing
Learn More