title: javax.persistence.TransactionRequiredException: No EntityManager with actual transaction available for current thread
body: <p>I created my first Spring MVC project with using Hibernate. My DAO layer is using JPA EntityManager for interaction with database.</p>
  
  <p><strong>GenericDao.java:</strong></p>
  
  <pre><code>@Repository
  public abstract class GenericDao&lt;T&gt; implements GeneralDao&lt;T&gt; {
  
      private Class&lt;T&gt; className;
  
      public GenericDao(Class&lt;T&gt; 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&lt;T&gt; getAll() throws DaoException;
  
  }
  </code></pre>
  
  <p><strong>GenericService.java</strong></p>
  
  <pre><code>@Service
  public abstract class GenericService&lt;T&gt; implements GeneralService&lt;T&gt; {
      private static Logger logger = Logger.getLogger(GenericService.class);
  
      @Autowired
      private GenericDao&lt;T&gt; 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&lt;T&gt; getAll() throws ServiceException {
          try {
              return dao.getAll();
          } catch (DaoException e) {
              logger.debug(e);
              throw new ServiceException(e.getMessage());
          }
      }
  
  }
  </code></pre>
  
  <p><strong>UserServiceImpl.java:</strong></p>
  
  <pre><code>@Service
  public class UserServiceImpl extends GenericService&lt;User&gt; 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&lt;User&gt; 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);
      }
  
  }
  </code></pre>
  
  <p><strong>UserController.java:</strong></p>
  
  <pre><code>@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;
      }
  
  }
  </code></pre>
  
  <p><strong>root-context.xml:</strong></p>
  
  <pre><code>&lt;?xml version="1.0" encoding="UTF-8"?&gt;
  &lt;beans xmlns="http://www.springframework.org/schema/beans"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xmlns:p="http://www.springframework.org/schema/p"
         xmlns:c="http://www.springframework.org/schema/c"
         xmlns:context="http://www.springframework.org/schema/context"
         xmlns:util="http://www.springframework.org/schema/util"
         xmlns:jdbc="http://www.springframework.org/schema/jdbc" xmlns:tx="http://www.springframework.org/schema/tx"
         xsi:schemaLocation="http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.1.xsd
          http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
          http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd
          http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc.xsd
          http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd"&gt;
  
      &lt;context:annotation-config /&gt;
  
      &lt;context:component-scan base-package="by.netcracker.artemyev.dao" /&gt;
      &lt;context:component-scan base-package="by.netcracker.artemyev.service" /&gt;
      &lt;context:component-scan base-package="by.netcracker.artemyev.web" /&gt;
  
      &lt;bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource"&gt;
          &lt;property name="url" value="jdbc:mysql://localhost:3306/airline?useSSL=false" /&gt;
          &lt;property name="driverClassName" value="com.mysql.jdbc.Driver"/&gt;
          &lt;property name="username" value="root"/&gt;
          &lt;property name="password" value="root"/&gt;
          &lt;property name="initialSize" value="5"/&gt;
          &lt;property name="maxTotal" value="10"/&gt;
      &lt;/bean&gt;
  
      &lt;bean id="entityManager" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"&gt;
          &lt;property name="dataSource" ref="dataSource" /&gt;
          &lt;property name="packagesToScan" value="by.netcracker.artemyev" /&gt;
          &lt;property name="jpaVendorAdapter"&gt;
              &lt;bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"&gt;
                  &lt;property name="showSql" value="true" /&gt;
                  &lt;property name="database" value="MYSQL" /&gt;
                  &lt;property name="databasePlatform" value="org.hibernate.dialect.MySQL5Dialect" /&gt;
              &lt;/bean&gt;
          &lt;/property&gt;
          &lt;property name="jpaProperties"&gt;
              &lt;props&gt;
                  &lt;prop key="hibernate.dialect"&gt;org.hibernate.dialect.MySQLDialect&lt;/prop&gt;
                  &lt;prop key="hibernate.show_sql"&gt;true&lt;/prop&gt;
                  &lt;prop key="debug"&gt;true&lt;/prop&gt;
                  &lt;prop key="connection.isolation"&gt;2&lt;/prop&gt;
                  &lt;prop key="hibernate.cglib.use_reflection_optimizer"&gt;true&lt;/prop&gt;
                  &lt;prop key="hibernate.hbm2ddl.auto"&gt;update&lt;/prop&gt;
              &lt;/props&gt;
          &lt;/property&gt;
          &lt;property name="jpaDialect" ref="jpaDialect" /&gt;
      &lt;/bean&gt;
  
      &lt;bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" /&gt;
  
      &lt;tx:annotation-driven transaction-manager="transactionManager" /&gt;
  
      &lt;bean id="jpaDialect" class="org.springframework.orm.jpa.vendor.HibernateJpaDialect" /&gt;
  
      &lt;bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"&gt;
          &lt;property name="entityManagerFactory" ref="entityManager" /&gt;
          &lt;property name="dataSource" ref="dataSource" /&gt;
          &lt;property name="jpaDialect" ref="jpaDialect" /&gt;
      &lt;/bean&gt;
  
  &lt;/beans&gt;
  </code></pre>
  
  <p><strong>Logs:</strong></p>
  
  <pre><code>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)
  </code></pre>
  
  <p><strong>Why I have this problem and how to fix it?</strong> </p>