我有一个Web服务DocGenerationServiceImpl,它使用DocRepository在表中插入(对于每种格式)一条记录,并将表示该记录的对象表示为DocFileDO。在for循环中,我可以获取在表中创建的记录的ID。对于每条记录,我将调用执行程序的execute方法,其中DocGenTask将在给定ID的情况下搜索记录。但是,例如,有3种格式,DocGenTask只能获取最后一条记录。它找不到前两个。尽管它使用的是hibernateTemplate。可以请教吗?
@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);
}
}
最佳答案
几件事
不要使用HibernateTemplate
,它应该从Hibernate 3.0.1(在2006年某个地方发布)开始就被弃用。直接使用SessionFactory
并使用getCurrentSession()
方法来使休眠的Session
可以运行。
您没有事务设置(从摘要中判断),要使用数据库,您需要适当的事务设置。
您的控制器正在做很多事情,所有这些都应该放在服务内部。
第一个重构您的存储库
@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
方法)。如前所述,您可能应该将控制器中找到的代码移至服务。控制器只不过是一个薄的集成层,它可以从Web转换为某种事物的内部表示,然后在某处启动服务/业务方法。服务/业务方法也是您的事务性工作单元,它要么全部成功,要么全部失败。