@Override
 public RET call() throws Exception {
   threadInitializer.initThread();
   try {
     LifeCycleManager.beforeRequest(request);
     try {
       Factory.setSessionFactory(sessionFactory, SessionType.CURRENT);
       return inner.call();
     } catch (Exception e) {
       System.err.println("Error while executing " + inner.getClass().getName());
       e.printStackTrace();
       throw e;
     } finally {
       LifeCycleManager.afterRequest();
     }
   } finally {
     threadInitializer.termThread();
   }
 }
 private <V> V execute(Callable<V> callable, int attempts, long sleep, boolean throwOnFail)
     throws Exception {
   V value = null;
   int tries = attempts;
   Throwable lastFail = null;
   while (tries > 0) {
     tries--;
     try {
       value = callable.call();
       if (value != null) {
         lastFail = null;
         break;
       }
     } catch (Throwable fail) {
       lastFail = fail;
     }
     try {
       Thread.sleep(sleep);
     } catch (InterruptedException e) {
       Thread.currentThread().interrupt();
       throw new RuntimeException(e);
     }
   }
   if (lastFail != null && (throwOnFail || LOGGER.isInfoEnabled())) {
     String emsg =
         String.format(
             "%s attempt(s) with a %sms sleep to execute [%s] failed. Last failure was [%s: %s]",
             attempts,
             sleep,
             callable.getClass().getSimpleName(),
             lastFail.getClass().getName(),
             lastFail.getMessage());
     if (throwOnFail) {
       throw new Exception(emsg, lastFail);
     } else {
       LOGGER.info(emsg);
     }
   }
   return value;
 }
 public CallableHandlerMethod(Callable<?> callable) {
   super(callable, ClassUtils.getMethod(callable.getClass(), "call"));
   this.setHandlerMethodReturnValueHandlers(
       ServletInvocableHandlerMethod.this.returnValueHandlers);
 }