Страницы

Поиск по вопросам

среда, 13 марта 2019 г.

javax.persistence.TransactionRequiredException: No EntityManager with actual transaction available for current thread

GenericDao.java:
@Repository public abstract class GenericDao implements GeneralDao {
private Class className;
public GenericDao(Class className) { this.className = className; }
@PersistenceContext private EntityManager entityManager;
public EntityManager getEntityManager() { return entityManager; }
@Override public void add(T object) { try { getEntityManager().persist(object); } catch (HibernateException e) { throw new DaoException(ErrorMessage.ADD_ENTITY_FAIL, e); } }
@Override public void update(T object) { try { getEntityManager().merge(object); } catch (HibernateException e) { throw new DaoException(ErrorMessage.UPDATE_ENTITY_FAIL, e); } }
@Override public void remove(T object) { try { getEntityManager().remove(object); } catch (HibernateException e) { throw new DaoException(ErrorMessage.REMOVE_ENTITY_FAIL, e); } }
@Override public T getById(int id) { try { return getEntityManager().find(this.className, id); } catch (HibernateException e) { throw new DaoException(ErrorMessage.GET_BY_ID_ENTITY_FAIL, e); } }
public abstract List getAll() throws DaoException;
}
GenericService.java
@Service public abstract class GenericService implements GeneralService { private static Logger logger = Logger.getLogger(GenericService.class);
@Autowired private GenericDao dao;
@Transactional @Override public void add(T object) throws ServiceException { try { dao.add(object); } catch (DaoException e) { logger.debug(e); throw new ServiceException(e.getMessage()); } }
@Transactional @Override public void update(T object) throws ServiceException { try { dao.update(object); } catch (DaoException e) { logger.debug(e); throw new ServiceException(e.getMessage()); } }
@Transactional @Override public void remove(T object) throws ServiceException { try { dao.remove(object); } catch (DaoException e) { logger.debug(e); throw new ServiceException(e.getMessage()); } }
@Transactional(readOnly = true) @Override public T getById(int id) throws ServiceException { try { return dao.getById(id); } catch (DaoException e) { logger.debug(e); throw new ServiceException(e.getMessage()); } }
@Transactional(readOnly = true) @Override public List getAll() throws ServiceException { try { return dao.getAll(); } catch (DaoException e) { logger.debug(e); throw new ServiceException(e.getMessage()); } }
}
UserServiceImpl.java:
@Service public class UserServiceImpl extends GenericService implements UserService { private static Logger logger = Logger.getLogger(UserServiceImpl.class);
@Autowired private UserDao userDao;
@Transactional @Override public String checkUser(String userLogin, String userPassword) throws ServiceException { String namePage = "errorAuthorization"; List userList; try { userList = userDao.getByLoginAndPassword(userLogin, userPassword); } catch (DaoException e) { logger.debug(e); throw new ServiceException(e.getMessage()); } if(userList.size() != 0) { return UserRoleChecker.defineUserPage(userList.get(0)); } return namePage; }
@Transactional @Override public void addUser(String userLogin, String userPassword, String userMail) throws ServiceException { Role role = new Role(0L, RoleType.USER); User user = new User(0L, userLogin, userPassword, userMail, role); add(user); }
}
UserController.java:
@Controller public class UserController { private static String className = UserController.class.getName(); private static Logger logger = Logger.getLogger(UserController.class.getName());
@Autowired private UserService userService;
@RequestMapping(value = "/check_user", method = RequestMethod.POST) public ModelAndView authorizationUser(HttpServletRequest request, HttpServletResponse response) { ModelAndView modelAndView = new ModelAndView(); String returnPage; try { returnPage = userService.checkUser(request.getParameter(RequestParameter.USER_LOGIN), request.getParameter(RequestParameter.USER_PASSWORD)); } catch (ServiceException e) { logger.debug(e); returnPage = ErrorHandler.returnErrorPage(e.getMessage(), className); } modelAndView.setViewName(returnPage); return modelAndView; }
@RequestMapping(value = "/add_user", method = RequestMethod.POST) public ModelAndView registrationUser(HttpServletRequest request, HttpServletResponse response) { ModelAndView modelAndView = new ModelAndView(); String returnPage = Page.SUCCESSFUL_REGISTRATION; try { userService.addUser(request.getParameter(RequestParameter.USER_LOGIN), request.getParameter(RequestParameter.USER_PASSWORD), request.getParameter(RequestParameter.USER_MAIL)); } catch (ServiceException e) { logger.debug(e); returnPage = ErrorHandler.returnErrorPage(e.getMessage(), className); } modelAndView.setViewName(returnPage); return modelAndView; }
}
root-context.xml:




org.hibernate.dialect.MySQLDialect true true 2 true update





logs:
org.springframework.web.servlet.FrameworkServlet 2017-05-10 22:23:59,107 DEBUG - Could not complete request javax.persistence.TransactionRequiredException: No EntityManager with actual transaction available for current thread - cannot reliably process 'persist' call at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:282) at com.sun.proxy.$Proxy27.persist(Unknown Source) at by.netcracker.artemyev.dao.GenericDao.add(GenericDao.java:35) at by.netcracker.artemyev.service.GenericService.add(GenericService.java:24) at by.netcracker.artemyev.service.impl.UserServiceImpl.addUser(UserServiceImpl.java:48) at by.netcracker.artemyev.web.UserController.registrationUser(UserController.java:45) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205) at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:133) at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:97) at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:827) at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:738) at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85) at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:963) at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:897) at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970) at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:872) at javax.servlet.http.HttpServlet.service(HttpServlet.java:661) at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846) at javax.servlet.http.HttpServlet.service(HttpServlet.java:742) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:230) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165) at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:199) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96) at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:475) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:80) at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:624) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:341) at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:495) at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66) at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:767) at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1354) at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) at java.lang.Thread.run(Thread.java:745)
Почему возникает эта ошибка и как её исправить?


Ответ

Проблема в том, что spring не строит прокси-объект поверх UserServiceImpl, а внедряет его напрямую в UserController, что видно из твоего исключения.
Причины, я полагаю, в том, что твой root-context.xml относится к контексту всего приложения, т.е. инициализируется через ContextLoaderListener. Внутри указанного контекста UserServiceImpl имеет транзакционность. Однако, у тебя также имеется некая конфигурация (тут лучше бы приложить web.xml) относящаяся к DispatcherServlet, в которой инициализируется UserController и как раз нет tx:annotation-driven. Соответственно в UserController попадет чистый бин, а не его прокси.
Быстро решить данную проблему можно убрав @Service с самого класса UserServiceImpl и определив его в root-context.xml

Комментариев нет:

Отправить комментарий