Использование DAO в компоненте, используемом запланированной задачей Spring - PullRequest
1 голос
/ 21 марта 2011

Я занимаюсь разработкой веб-приложения с использованием Struts2 + Spring и сейчас пытаюсь добавить запланированное задание. Я использую планирование задач 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" />

Так что это работает безупречно в веб-приложении. Но теперь у меня возникает проблема при создании запланированного задания:

<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>

Это выполняет метод sendMail в моем классе emailService каждые 30 секунд. И мой emailService правильно ввел DAO. Дело в том, что я могу получать объекты с помощью моего DAO, используя именованные запросы findById, но когда я пытаюсь получить доступ к любому свойству, отображаемому Hibernate, например, связанным коллекциям или объектам, я получаю «LazyInitializationException: не удалось инициализировать прокси - нет сеанса» , Я не знаю, что не так, так как я считаю, что запланированная задача управляется Spring, поэтому у нее не должно быть проблем с использованием Spring DAO. Я должен сказать, что я использую фильтр openSessionInView для своих действий в Struts, поэтому, возможно, мне нужно нечто подобное для этой запланированной задачи.

Любая помощь или предложение будет оценено, спасибо!

Редактировать : Наконец-то я нашел способ это исправить. Я поменял свой обычный Дао на тот, где я могу решить, когда начинать и совершать транзакцию. Поэтому, прежде чем что-то делать, я начинаю транзакцию, а затем все работает хорошо. Так что я до сих пор не знаю точно, что является причиной проблемы, и если когда-нибудь я смогу использовать свой обычный DAO, на данный момент я остаюсь с этим решением.

1 Ответ

4 голосов
/ 21 марта 2011

OpenSessionInView вам не поможет, потому что у вас нет веб-контекста. Вам необходимо декларативное управление транзакциями Spring .

В большинстве случаев вам нужно всего лишь 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, чтобы включить это)

...