2011-03-21 98 views
1

我正在開發使用的Struts2 +春季Web應用程序中使用Spring上的bean創建一個DAO,現在我想添加一個計劃任務。我使用Spring的任務調度來做到這一點。在我的applicationContext我:使用計劃任務

<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> 
... 
</bean> 

<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> 
    <property name="dataSource" ref="dataSource" /> 
    <property name="jpaVendorAdapter"> 
     <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"> 
      <property name="database" value="MYSQL" /> 
     </bean> 
    </property> 
</bean> 

<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"> 
    <property name="entityManagerFactory" ref="entityManagerFactory" /> 
</bean> 

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

然後,我有我的DAO使用此的entityManagerFactory:

<bean id="dao" class="data.GenericDAO" /> 

所以這完美的作品在Web應用程序中。但是現在我在創建計劃任務時遇到問題:

<task:scheduled-tasks scheduler="notifier"> 
    <task:scheduled ref="emailService" method="sendMail" fixed-rate="30000" /> 
</task:scheduled-tasks> 

<task:scheduler id="notifier" pool-size="10" /> 

<bean id="emailService" class="services.emailService" > 
    <property name="dao" ref="dao" /> 
</bean> 

這會每30秒對我的emailService類執行sendMail方法。我的emailService有正確注入的DAO。問題是,我可以取得與使用findById命名查詢我的DAO對象,但是當我嘗試訪問由Hibernate,映射的任何財產,如相關的集合或實體,我得到一個「LazyInitializationException異常:無法初始化代理 - 沒有會話」 。我不知道什麼是錯的,因爲我認爲計劃任務是由Spring管理的,所以使用Spring管理的DAO應該沒有問題。我必須說我在我的struts動作中使用了openSessionInView過濾器,所以也許我需要類似這個計劃任務的東西。

任何幫助或建議將感激,謝謝!

編輯:最後,我找到了一種方法來解決這個問題。我改變了我的常規道,在那裏我可以決定何時開始和提交交易。所以在做任何事情之前,我開始一個交易,然後一切正常。所以我仍然不知道究竟是什麼原因導致了問題,並且如果有一天我能夠使用我的常規DAO,那麼我現在就要使用這個解決方案。

回答

4

OpenSessionInView不會幫你,因爲你沒有一個網絡環境。你需要Spring的Declarative Transaction Management

在大多數情況下,你需要做的就是這個XML:

<!-- JPA, not hibernate --> 
<bean id="myTxManager" class="org.springframework.orm.jpa.JpaTransactionManager"> 
    <property name="entityManagerFactory" ref="entityManagerFactory"/> 
</bean>  

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

<!-- without backing interfaces you probably also need this: --> 
<aop:config proxy-target-class="true"> 

(註釋你的EmailService類爲@Transactional,使這個)

+0

我註解我emailService爲@Transactional(其迫使我包含CGlib),但錯誤仍然存​​在。我一直得到:LazyInitializationException:無法初始化代理 - 沒有會話 – 1000i1 2011-03-21 08:52:40

+0

@ 1000i1如果您有支持接口,則不需要CGLib,請參見[代理機制](http://static.springsource.org/spring/docs/3.0 .X /彈簧框架參考/ HTML/aop.html#AOP-代理) – 2011-03-21 09:11:58

+0

出於測試目的,我不介意使用CGLIB,現在我專注於固定LazyInitializationException中。如果我能擺脫這一點,那麼我會看看這些代理機制。感謝您的回覆! – 1000i1 2011-03-21 09:17:44