I want to create an exception log in the database when an @Async
operation fails with an exception.
You can see the implementation for AsyncExecutorConfiguration
and AsyncExceptionHandler
classes below.
Inside AsyncExceptionHandler
class, when I call a service that tries to access the database, I am getting: org.hibernate.HibernateException: Could not obtain transaction-synchronized Session for current thread
@Configuration
@EnableAsync
public class AsyncExecutorConfiguration implements AsyncConfigurer {
@Autowired
private AsyncExceptionHandler asyncExceptionHandler;
private static final int CORE_POOL_SIZE = 3;
private static final int MAX_POOL_SIZE = 3;
private static final int QUEUE_CAPACITY = 24;
private static final String THREAD_NAME_PREFIX = "AsynchThread-";
@Override
public Executor getAsyncExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(CORE_POOL_SIZE);
executor.setMaxPoolSize(MAX_POOL_SIZE);
executor.setQueueCapacity(QUEUE_CAPACITY);
executor.setThreadNamePrefix(THREAD_NAME_PREFIX);
executor.initialize();
return executor;
}
@Override
public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
return asyncExceptionHandler;
}
}
@Component
public class AsyncExceptionHandler implements AsyncUncaughtExceptionHandler {
@Autowired
private NotificationService notificationService;
@Override
@Transactional(rollbackFor = Exception.class, readOnly = false)
public void handleUncaughtException(Throwable ex, Method method, Object... params) {
AsyncErrorLog log = new AsyncErrorLog(ex);
notificationService.saveLogAndNotify(log); // throws exception "Could not obtain transaction-synchronized Session for current thread"
}
}
@Service
public class MyServiceImpl implements MyService {
@Override
@Async
@Transactional(rollbackFor = Exception.class, readOnly = false, propagation = Propagation.REQUIRES_NEW)
public void doSomething(Long id) {
// I can execute database operations here
}
...
@Async
function itself already has a valid session. What should I do to have a valid session in AsyncExceptionHandler
class too?
--
UPDATE
Here is the simplified implementations for NotificationServiceImpl
and LogDaoImpl.class
where we get the error.
@Service
public class NotificationServiceImpl implements NotificationService {
@Autowired
private LogDao logDao;
@Override
@Transactional(rollbackFor = Exception.class, readOnly = false)
public void saveLogAndNotify(Log log) {
return logDao.createLog(log);
}
@Repository
public class LogDaoImpl{
@Autowired
protected SessionFactory sessionFactory;
@Override
public void createLog(Log log) {
sessionFactory.getCurrentSession().saveOrUpdate(log);
}