I have a project based on Spring 4.0 and Hibernate 4, specifically, Spring MVC.
Hibernate's session is being created byOpenSessionInViewFilter
for each request in controller.
Now, I'm trying to start a new Thread inside controller's method (to do a long process). Apparently, OpenSessionInViewFilter is closing the session after request finishes. Then, when my Thread starts, there isn't session anymore and I get this error:
org.hibernate.HibernateException: No Session found for current thread
Here is the basis structure of classes, from Controller to my Callable component. IReportService extends Callable.
OBS: I've been tried to use spring's @Async
annotation, but it stills not working. I put REQUIRES_NEW
on Service trying to get a new transaction, but it failed even changed to NESTED.
@Controller
@RequestMapping(value = "/action/report")
@Transactional(propagation = Propagation.REQUIRED)
public class ReportController {
@Autowired
private IReportService service;
private final Map<Long, Future> tasks = new HashMap();
@RequestMapping(value = "/build")
public String build(@RequestParam Long id) {
ExecutorService executor = Executors.newSingleThreadExecutor();
Future<StatusProcesso> future = executor.submit(service);
tasks.put(id, future);
return "wait-view";
}
@RequestMapping(value = "/check", method = RequestMethod.GET)
public @ResponseBody Map<String, Object> check(@RequestParam Long id) {
String status = null;
try {
Future foo = this.processos.get(id);
status = foo.isDone() ? "complete" : "building";
} catch (Exception e) {
status = "failed";
}
return new ResponseBuilder()
.add("status", status)
.toSuccessResponse();
}
// Another operations...
}
@Service
@Transactional(propagation = Propagation.REQUIRES_NEW)
public class ReportService implements IReportService {
@Autowired
private IReportDAO dao;
@Override
public Status call() {
Status status = new Status();
// do long operation and use DAO...
return status;
}
}