Wednesday, November 12, 2014

Sunday, November 2, 2014

Springs @Async and @Transactional issue

While using this combination I used to get the below error:

org.hibernate.HibernateException: No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here

To fix this issue we have to design out service layer/DAO.. as below.: 

Controller Code:

@Autowired
ComputationService computationService;

Below is the controller method :
@RequestMapping(value ="/saveAndBuild", method = RequestMethod.POST)
public String saveAndBuild (Model model, final HttpServletRequest request,
@ModelAttribute(REVIEW_AND_BUILD_FORM) ReviewAndBuildForm reviewAndBuildForm) {
computationService.startComputations(reviewAndBuildForm.getFile(), reviewAndBuildForm.getReportId(),computationService.updateStatusByFileId(reviewAndBuildForm.getFile()));

This is the service class which creates instances of @Async methods classes:
Here we need to say @EnableAsync at class level indicating to accept async process,

@Service
@EnableAsync

public class ComputationServiceImpl implements ComputationService {


Method which actually calls the Async methods from this interface. 
@Override
public void startComputations(Long fileId, Long reportId,VaDdFileInfo vaDdFileInfo){
asyncCompuationService.executeComputationAsync(fileId,reportId,vaDdFileInfo);


}


Below is the sample code for @Async method:

Note:Make sure here you should not include @transaction at class level or method level.You need to call another service which actually has business layer which contains the @Transcation attribute


@Override
@Async
public void executeComputationAsync(Long fileId, Long reportId,
VaDdFileInfo vaDdFileInfo) {

computationProcessService.executeComputationAsync(fileId, reportId, vaDdFileInfo);


}

Below is the actual Transactional point

/**
* {@inheritDoc}
*/
@Override
@Transactional(value = "npTransactionManager", propagation = Propagation.REQUIRED)
public void executeComputationAsync(Long fileId, Long reportId,
VaDdFileInfo vaDdFileInfo) {

try{
List<VaDdFileData> vaDdFileDataList = vaDdFileDataDao.findByFileId(fileId);