简体   繁体   中英

HibernateTemplate not getting the object when called through TaskExecutor

I have a web service DocGenerationServiceImpl that inserts (for every format) a record in the table using DocRepository and object representing the record as DocFileDO. In the for-loop, I can get the id of the record that was created in the table. For each record, I will call the executor's execute method where DocGenTask will search for the record given the id. However, for example, there are 3 formats, the DocGenTask is able to get only the last record. The first 2 it cannot find. Although it's using hibernateTemplate. Can please advise?

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

A couple of things

  1. Don't use HibernateTemplate it should be considered deprecated as of Hibernate 3.0.1 (which was released somewhere in 2006). Use the SessionFactory directly and use the getCurrentSession() method to get a hibernate Session to operate on.

  2. You don't have transactions setup (judging from the snippets), to work with a databse you need proper transaction setup.

  3. Your controller is doing much, all of this should be inside a service.

The first refactor your repository

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

}

Now your code will probably fail due to improper transaction setup. Add @Transactional to all the methods (or class) that need a transaction (like the saveDocFile method).

As mentioned you probably should move the code found in the controller to a service. The controller should be nothing more then a thin integration layer converting from the web to an internal representation of something and then kick off a service/business method somewhere. This service-/business-method is also your transactional unit-of-work it either all succeeds or all fails.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM