spring+hibernate的session問題

在spring框架和hibernate框架集成的時候,根據不同的需求,或者個人的習慣問題。會出現多種多樣的數據訪問層的代碼。本篇文章揀出幾個典型的問題,加以淺談。

DAO層中的某個類如果沒有繼承自HibernateDaoSupport。而是使用SessionFactory獲取對象。(配置文件中已經配置了sessionFactory對象)。可能使用註解進行了注入。

獲取session的方式:

1、sessionFactory.openSession();

該方式獲取的session是不受spring管理的,在和數據庫交互的過程中,需要手動的打開和關閉事務。並且關於session的問題,還是那個原則“誰創建誰關閉”。意思就是,必須手動關閉session。哪怕你使用了@Transactional註解。

2、sessionFactory.getCurrentSession();

在一不小心的情況下,可能發生一個異常:

org.hibernate.HibernateException: No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here
 at org.springframework.orm.hibernate3.SpringSessionContext.currentSession(SpringSessionContext.java:63)
 at org.hibernate.impl.SessionFactoryImpl.getCurrentSession(SessionFactoryImpl.java:622)

第一種方法:

這個時候可以加入spring提供的事務管理機制來改變這個問題。例如加上@Transactional註解,不過事先要在配置文件中定義好。示例如下:

<tx:annotation-driven transaction-manager="transactionManager" />

 <bean id="transactionManager"
  class="org.springframework.orm.hibernate3.HibernateTransactionManager">
  <property name="sessionFactory" ref="sessionFactory"></property>
 </bean>

 

當然也要引入tx的命名空間。這個時候,不需要顯式的開啓事務和關閉session的操作,因爲spring已經替我們做了。

第二種方法:

如果你不打算讓spring來管理事務。你可以在配置文件中,加入:

<prop key="hibernate.current_session_context_class">thread</prop>

要是出現org.hibernate.HibernateException:persist is not valid without active transaction那你就要手動的來開啓和關閉事務了。這種情況加入@Transactional註解也是沒有作用的。這種情況下session不需要手動關閉。

 

最後來個小技巧:

如果沒有使用spring的組件掃描機制的話,需要在配置文件中配置DAO層的一些類(繼承自HibernateDaoSupport)。

其中可能會出現這樣的代碼:

<bean id="personDao" class="com.dao.PersonDao">

<property name="sessionFactory" ref="sessionFactory" />

</bean>

其中<property name="sessionFactory" ref="sessionFactory" />這個配置,可能會重複N次。

這時候,可以在配置文件中加入:

<bean id="hibernateDaoSupport" abstract="true" class="org.springframework.orm.hibernate3.support.HibernateDaoSupport">

<propery name="sessionFactory" ref="sessionFactory"/>

</bean>

然後再:

<bean id="personDao" class="com.dao.PersonDao" parent="hibernateDaoSupport" />

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章