Java 在Spring计划任务使用的Bean上使用DAO

Java 在Spring计划任务使用的Bean上使用DAO,java,hibernate,spring,jpa,dao,Java,Hibernate,Spring,Jpa,Dao,我正在使用Struts2+Spring开发一个web应用程序,现在我正在尝试添加一个计划任务。我使用Spring的任务调度来实现这一点。在我的应用程序上下文中,我有: <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> ... </bean> <bean id="entityManagerFactory" class="org.spri

我正在使用Struts2+Spring开发一个web应用程序,现在我正在尝试添加一个计划任务。我使用Spring的任务调度来实现这一点。在我的应用程序上下文中,我有:

<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更改了我的常规Dao。所以在做任何事情之前,我先启动一个事务,然后一切正常。因此,我仍然不知道到底是什么原因导致了这个问题,如果有一天我能够使用我的常规DAO,目前我仍然使用这个解决方案。

OpenSessionInView对您没有帮助,因为您没有web上下文。你需要春天的阳光

在大多数情况下,您需要做的只是以下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
以启用此功能)

OpenSessionInView对您没有帮助,因为您没有web上下文。你需要春天的阳光

在大多数情况下,您需要做的只是以下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
以启用此功能)

我已将我的EmailService注释为@Transactional(这迫使我包含CGlib),但错误仍然存在。我不断得到:LazyInitializationException:无法初始化代理-否Session@1000i1如果您有一个支持接口,就不需要CGLib,请参见出于测试目的,我不介意使用CGLib,现在我专注于修复LazyInitializationException。如果我能摆脱它,那么我将看看这些代理机制。谢谢你的回复@1000i1我想你也需要proxy target class=true(见我的更新)@1000i1哦,我刚刚意识到你在使用JPA,那么你需要一个不同的事务管理器。相应地编辑了我的答案。我已经将我的emailService注释为@Transactional(这迫使我包含CGlib),但错误仍然存在。我不断得到:LazyInitializationException:无法初始化代理-否Session@1000i1如果您有一个支持接口,就不需要CGLib,请参见出于测试目的,我不介意使用CGLib,现在我专注于修复LazyInitializationException。如果我能摆脱它,那么我将看看这些代理机制。谢谢你的回复@1000i1我想你也需要proxy target class=true(见我的更新)@1000i1哦,我刚刚意识到你在使用JPA,那么你需要一个不同的事务管理器。据此编辑了我的答案。