2013-11-27 2 views
0

DocRepository를 사용하는 테이블의 레코드와 DocFileDO로 레코드를 나타내는 객체를 (모든 형식으로) 테이블에 삽입하는 웹 서비스 DocGenerationServiceImpl이있다. for-loop에서 테이블에 생성 된 레코드의 ID를 얻을 수 있습니다. 각 레코드에 대해 실행 프로그램의 execute 메소드를 호출하여 DocGenTask가 주어진 id에 해당하는 레코드를 검색합니다. 그러나 예를 들어 3 가지 형식이 있으며 DocGenTask는 마지막 레코드 만 가져올 수 있습니다. 처음 2 개는 찾을 수 없습니다. hibernateTemplate을 사용하고 있지만. 제발 조언 해 줄 수 있니?HibernateTemplate이 TaskExecutor를 통해 호출 될 때 객체를 가져 오지 않는다.

@RestfulService 
@Controller 
@RequestMapping("/docs") 
public class DocGenerationServiceImpl { 

    @Autowired 
    private TaskExecutor taskExecutor; 

    @Autowired 
    private DocRepository docRepository; 

    @RequestMapping(value = "/generate", method = RequestMethod.POST) 
    @ResponseBody 
    public String generatedDocFile(DOCParam param) { 

     for(String format : param.getFormatList()) { 
       DocFileDO docFileDO = new DocFileDO(); 
       ... 
       docRepository.saveDocFile(docFileDO); 
       log.debug("docFileDO id = " + docFileDO.getId()); 

       DocGenTask task = new DocGenTask(docFileDO.getId()); 
       task.setDocRepository(docRepository); 
       taskExecutor.execute(task); 
     } 
    } 
} 


@Repository 
public class DocRepository { 
    @Autowired 
    private HibernateTemplate hibernateTemplate; 

    public DocFileDO saveDocFile(DocFileDO docFile) { 
     hibernateTemplate.save(docFile); 
     hibernateTemplate.flush(); 
     return docFile; 
    } 
    public DocFileDO getDocFile(Long docFileId) { 
     return hibernateTemplate.get(DocFileDO.class, docFileId); 
    } 

} 

public class DocGenTask implements Runnable { 
    public void run() { 
     generate(); 
    } 
    private void generate() { 
     DocFileDO docFileObj = docRepository.getDocFile(docFileId); 
    } 
} 

답변

1

가 최대 절전 모드 3.0.1 추천되지 고려되어야한다 HibernateTemplate를 사용하지 마십시오 일

  1. 의 부부 (2006 년 어딘가에 공개 된). SessionFactory을 직접 사용하고 getCurrentSession() 방법을 사용하여 최대 절전 모드 Session을 작동시킵니다.

  2. 적절한 트랜잭션 설정이 필요한 데이터베이스로 작업 할 트랜잭션 설정 (스 니펫으로 판단)이 없습니다.

  3. 컨트롤러가 많이 작동합니다.이 모든 것은 서비스 안에 있어야합니다.

    @Repository  
    public class DocRepository { 
        @Autowired 
        private SessionFactory sf; 
    
        public DocFileDO saveDocFile(DocFileDO docFile) { 
         Session session = sf.getCurrentSession(); 
         session.save(docFile); 
         return docFile; 
        } 
        public DocFileDO getDocFile(Long docFileId) { 
         return sf.getCurrentSession().get(DocFileDO.class, docFileId); 
        } 
    
    } 
    

    지금 코드가 아마 부적절한 거래 설정으로 인해 실패합니다

첫 번째 리팩토링 저장소. 트랜잭션이 필요한 모든 메소드 (또는 클래스)에 @Transactional을 추가하십시오 (예 : saveDocFile 메소드).

언급 한대로 컨트롤러에서 발견 된 코드를 서비스로 옮겨야 할 것입니다. 컨트롤러는 웹에서 무언가의 내부 표현으로 전환 한 다음 어딘가에서 서비스/비즈니스 방법을 시작해야합니다. 이 서비스/비즈니스 방법은 모두 성공하거나 모두 실패한 트랜잭션 작업 단위입니다.

관련 문제