2011-03-10 2 views
0

나는 Hibernate3과 Spring3을 모두 처음 접했고 최대 절전 모드의 지연 참조 초기화와 관련된 문제가 있습니다. 목적.주석을 사용하는 모듈화 된 Spring 어플리케이션에서 Hibernate 3의 "부모"어플리케이션 컨텍스트로 정의 된 세션이 없으므로 LazyInitializationException이 발생했습니다.

나는 완전히 포함 된 DAO 및 서비스를 가지고 있습니다. 도메인 객체는 hbm2java와 리버스 엔지니어링 파일을 사용하여 생성됩니다. 내 서비스 객체에서 주석 (@Transactional)을 사용하여 찾은 모범 사례를 따라했습니다.

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

내 최대 절전 모드 :

오전 데 문제는 내가 주석 처리 및 트랜잭션 관리를위한 내 service.jar에서 다음 봄 구성을 가지고있다 (이 가이드 http://carinae.net/2009/11/layered-architecture-with-hibernate-and-spring-3/ 나에게 매우 도움이되었다). cfg.xml은 단순히 내 데이터 소스 세부 정보와 도메인 객체의 주석 매핑 목록입니다.

서비스 계층과 DAO 계층을 사용하고 있습니다.

@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(); 

    } 

코드의이 수집은 받는다는 모듈로 패키지화되고, I가 개발하고 스케줄링 및 워크 플로우 모듈은 다른 스프링 프로젝트 의존성로 포함 된 DAO 층 . 관련 applicationContext.xml 정보

<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() 
      + "]"); 
.... 

내가 할 (내가받을 이유가 이해)을 LOG.info 문 동안 LazyInitializationException이 있습니다. 이 트랜잭션은 포함 된 서비스 의존 관계의 spring-hibernate 컨텍스트에 의해 관리되며이 컨텍스트에서는 사용할 수 없습니다. 내가 이해하지 못하는 것은 LazyInitializationException을 막기 위해 트랜잭션 관리를이 계층에 포함시키는 적절한 방법이다. 나는 단순히는 서비스 종속성에 정의 된 TransactionManager를 볼 수 없었다 불평 비즈니스 계층의 애플리케이션 컨텍스트에

<bean id="txInterceptor" class="org.springframework.transaction.interceptor.TransactionInterceptor" /> 

를 추가했습니다. 그러나 @Transactional을 Workflow 스테퍼의 .execute()에 추가하면 종속성에서 구성을 "상속"합니다.

무엇이 누락 되었습니까?

답변

0

응용 프로그램에서 OpenEntityManagerInView 인터셉터를 사용하여 지연 초기화를 수행 할 수 있습니다. 그렇지 않으면 getPendingEvents() 메소드 내부의 이벤트 목록에있는 ApplicationEvent 중 하나에서 일부 getter 메소드를 호출 할 수 있습니다. 이렇게하면 목록 안에있는 객체를 열심히로드 할 수 있습니다.

편집 : OpenEntityManagerInView가 개체가 아닐 수 있으므로 응용 프로그램에서 JPA를 사용하지 않는 것 같습니다. 두 번째 옵션은 계속 작동해야합니다.

관련 문제