天天看點

spring 中配置sessionFactory及用法

方法一:

1、在Spring的applicationContext.xml中配置bean

 <!-- 啟用注解注入  -->

      <context:annotation-config />

      <!-- spring掃描的包 -->

      <context:component-scan base-package="com.iven"/> 

      <!-- 配置資料源 -->

      <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" >

       <property name="url" value="jdbc:mysql://172.25.9.99:3306/fzghc" />

       <property name="username" value="root"></property>

       <property name="password" value="123456"></property>       

      </bean>     

       <!-- 配置Spring的SessionFactory -->

      <bean id="sessionFactory"        class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">

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

        <property name="annotatedClasses">

            <list>

                <value>com.iven.entity.User</value>

                <value>com.iven.entity.Repairs</value>

            </list>

        </property>       

        <property name="hibernateProperties">

            <value>

    <!-- hibernate.dialect=org.hibernate.dialect.SQLServerDialect -->

    hibernate.show_sql=true    

            </value>

      </bean>

      <!-- 添加事務管理 -->

      <bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">

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

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

  <!-- 添加事務管理 -->

      </bean>      

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

      <bean id="txManager"       class="org.springframework.orm.hibernate4.HibernateTransactionManager">

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

      <tx:advice  id="txAdvice" transaction-manager="txManager">

         <tx:attributes>

            <!-- all methods starting with 'get' are read-only -->

            <tx:method name="queryByUsername" read-only="true"/>   

            <!-- other methods use the default transaction settings (see below) -->

            <tx:method name="*" />              

          </tx:attributes>

      </tx:advice>

      <aop:config>

        <aop:pointcut expression="execution(* com.iven.dao.*.*(..))"           id="fooServiceOperation"/>

        <aop:advisor advice-ref="txAdvice" pointcut-ref="fooServiceOperation"/>

      </aop:config>

2、添加類BaseSessionFactoryImpl用于擷取Session,類BaseSessionFactoryImpl的内容如下:

public class BaseSessionFactoryImpl {

 @Resource(name="sessionFactory")

 private SessionFactory sessionFactory=null;

 public Session getSession(){

  return sessionFactory.getCurrentSession();

 }

}

3、在Dao層擷取Session,

public class UserDaoImplextends BaseSessionFactoryImpl

{

 public User queryByUsername(String userName) {    

     User user=null;

     String sql="select user from User user where user.userName="+userName;

     try {

       user=(User) getSession().get(User.class, 1);   

     } catch (Exception e) {

      e.printStackTrace();

     }     

    return user;

4.重點注意事項

SessionFactory的getCurrentSession并不能保證在沒有目前Session的情況下會自動建立一個新的,這取決于CurrentSessionContext的實作,SessionFactory将調用CurrentSessionContext的currentSession()方法來獲得Session。

在Spring中,如果我們在沒有配置TransactionManager并且沒有事先調用SessionFactory.openSession()的情況直接調用getCurrentSession(),那麼程式将抛出“No

Session found for current thread”異常。

   如果配置了TranactionManager并且通過@Transactional或者聲明的方式配置的事務邊界,那麼Spring會在開始事務之前通過AOP的方式為目前線程建立Session,此時調用getCurrentSession()将得到正确結果。

然而,産生以上異常的原因在于Spring提供了自己的CurrentSessionContext實作,如果我們不打算使用Spring,而是自己直接從hibernate.cfg.xml建立SessionFactory,并且為在hibernate.cfg.xml

中設定current_session_context_class為thread,也即使用了ThreadLocalSessionContext,那麼我們在調用getCurrentSession()時,如果目前線程沒有Session存在,則會建立一個綁定到目前線程。

Hibernate在預設情況下會使用JTASessionContext,Spring提供了自己SpringSessionContext,是以我們不用配置current_session_context_class,當Hibernate與Spring內建時,将使用該SessionContext,故此時調用getCurrentSession()的效果完全依賴于SpringSessionContext的實作。

在沒有Spring的情況下使用Hibernate,如果沒有在hibernate.cfg.xml中配置current_session_context_class,有沒有JTA的話,那麼程式将抛出"No

CurrentSessionContext

configured!"異常。此時的解決辦法是在hibernate.cfg.xml中将current_session_context_class配置成thread。

在Spring中使用Hibernate,如果我們配置了TransactionManager,那麼我們就不應該調用SessionFactory的openSession()來獲得Sessioin,因為這樣獲得的Session并沒有被事務管理。

至于解決的辦法,可以采用如下方式:

1. 在spring 配置檔案中加入

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

并且在處理業務邏輯的類上采用注解

@Service

public class CustomerServiceImpl implements CustomerService {

@Transactional

public void saveCustomer(Customer customer) {

customerDaoImpl.saveCustomer(customer);

...

另外在 hibernate 的配置檔案中,也可以增加這樣的配置來避免這個錯誤:

<property name="current_session_context_class">thread</property>