Я довольно новичок как в Hibernate3, так и в Spring3, и у меня возникла проблема, связанная с инициализацией отложенных ссылок объекта hibernate.
У меня есть полный дао и сервис. Доменные объекты создаются с использованием hbm2java и файла обратного инжиниринга. Я следовал рекомендациям по использованию аннотаций (@Transactional) в своих сервисных объектах. (Это руководство было ОЧЕНЬ полезно для меня http://carinae.net/2009/11/layered-architecture-with-hibernate-and-spring-3/)
Проблема, с которой я столкнулся, заключается в том, что у меня есть следующая пружинная конфигурация в моем service.jar для обработки аннотаций и управления транзакциями:
<context:annotation-config />
<context:component-scan base-package="com.barlingbay.dodmerb.persistence" />
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="configLocation">
<value>classpath:hibernate.cfg.xml</value>
</property>
</bean>
<tx:annotation-driven/>
<bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor"/>
<bean id="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
Мой hibernate.cfg.xml - это просто список моих данных источника данных и сопоставлений аннотаций объектов домена.
Я использую сервисный слой и слой дао.
@Service
public class ApplicantEventServiceImpl implements ApplicantEventService {
@Autowired(required = true)
private ApplicantEventDao appEventDao;
@Transactional
public List<ApplicantEvent> getEvents() {
return this.appEventDao.getPendingEvents();
}
и слой дао
@Repository
public class ApplicantEventDaoImpl implements ApplicantEventDao {
@Autowired(required = true)
private SessionFactory sessionFactory;
public List<ApplicantEvent> getPendingEvents() {
sessionFactory.getCurrentSession().beginTransaction(); // (If I don't have this, my junit test fails because of no active transaction, but that's a different issue)
return sessionFactory.getCurrentSession()
.createQuery("from ApplicantEvent").list();
}
Эта коллекция кода упакована как модуль maven и включена в качестве зависимости в другой весенний проект, который является модулем планирования и рабочего процесса, который я разрабатываю. Соответствующее applicationContext.xml info
<bean id="workflowStepper" class="com.barlingbay.merb.scheduler.WorkflowStepper" />
<bean id="jobDetailWorkflowStepper"
class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean"
p:targetObject-ref="workflowStepper" p:targetMethod="execute" />
<bean id="triggerJobDetailTicketRegistryCleaner" class="org.springframework.scheduling.quartz.SimpleTriggerBean"
p:jobDetail-ref="jobDetailWorkflowStepper" p:startDelay="2000"
p:repeatInterval="5000" />
<bean id="scheduler"
class="com.barlingbay.merb.scheduler.AutowiringSchedulerFactoryBean" />
И базовый Workflow.java:
public class WorkflowStepper implements IWorkflowStepper,
ApplicationContextAware {
private final Logger LOG = Logger.getLogger(this.getClass());
private ApplicationContext applicationContext;
// @Transactional
public void execute() {
ApplicantEventService appEvent = (ApplicantEventService) applicationContext
.getBean("applicantEventServiceImpl");
List<ApplicantEvent> events = appEvent.getEvents();
for (ApplicantEvent event : events) {
try {
LOG.info(event.getApplicant().getUsername() + "[" + event.getName()
+ "]");
....
Я получаю (и понимаю, почему я получаю) исключение LazyInitializationException во время выполнения инструкции LOG.info. Транзакция управляется контекстом spring-hibernate во включенной зависимой службе и не доступна в этом контексте. Что я не понимаю, так это правильный способ включить управление транзакциями в этот уровень (и далее), чтобы предотвратить исключение LazyInitializationException. Я попытался просто добавить
<bean id="txInterceptor" class="org.springframework.transaction.interceptor.TransactionInterceptor" />
к контексту приложения бизнес-уровня, который жаловался на то, что не может видеть менеджер транзакций, определенный в зависимости службы. Однако, если я добавлю @Transactional в .execute () степпера Workflow, он «унаследует» конфигурацию от зависимости.
Чего мне не хватает?