0

I am trying using Hibernate with spring & performing user Registration action. Here is the code

@Repository
@Transactional(value = "myTransactionManager")
public class UserFunctionsDAOImpl implements UserFunctionsDAO {

    @Autowired
    private SessionFactory sessionFactory;

    public void setSessionFactory(SessionFactory sessionFactory)
    {
        this.sessionFactory = sessionFactory;
    }

    @Override
    public String registerUser(Users user) {
        // TODO Auto-generated method stub

        Query query = this.sessionFactory.getCurrentSession().createQuery("SELECT COUNT(*) FROM Users WHERE emailID = :email_ID OR mobileNo = :mobile_No");
        query.setString("email_ID", user.getEmailID());
        query.setString("mobile_No", user.getMobileNo());

        if(((long)query.uniqueResult()) > 0)
            return "Email or Mobile number already exists";
        else
        {
            user.setUsetType("u");
            Session session = this.sessionFactory.getCurrentSession();
            session.beginTransaction();
            session.save(user);
            session.getTransaction().commit();
            session.close();

            return "User Registered Successfully";
        }
    }

}

In the above code, I am getting the error

org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.hibernate.TransactionException: nested transactions not supported
    org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:979)
    org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:869)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:647)
    org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:843)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:728)

root cause

org.hibernate.TransactionException: nested transactions not supported
    org.hibernate.engine.transaction.spi.AbstractTransactionImpl.begin(AbstractTransactionImpl.java:154)
    org.hibernate.internal.SessionImpl.beginTransaction(SessionImpl.java:1471)
    com.pir.dao.UserFunctionsDAOImpl.registerUser(UserFunctionsDAOImpl.java:49)
    sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    java.lang.reflect.Method.invoke(Method.java:606)
    org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:317)
    org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190)
    org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
    org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:99)
    org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:281)
    org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
    org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:207)
    com.sun.proxy.$Proxy620.registerUser(Unknown Source)
    com.pir.service.UserFunctionsServiceImpl.registerUser(UserFunctionsServiceImpl.java:36)
    com.pir.controller.RegisterController.addUserController(RegisterController.java:63)
    sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    java.lang.reflect.Method.invoke(Method.java:606)
    org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:221)
    org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:137)
    org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:110)
    org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:776)
    org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:705)
    org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85)
    org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:959)
    org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:893)
    org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:967)
    org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:869)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:647)
    org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:843)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:728)

How to remove this error?

Harshit
  • 5,147
  • 9
  • 46
  • 93

1 Answers1

3

The @Transactional annotation is at fault here. Spring will proxy your @Repository Bean to wrap all public functions in code that starts a new Transaction.

So, calling the method will create a transaction inside the Spring Proxy and then you try to start another transaction with your own code.

To solve this you could either just not start another transaction yourself and just use the one provided by Spring or you could move the @Transactional to the methods where you actually need it, instead of every public method in the class.

alexbt
  • 16,415
  • 6
  • 78
  • 87
mhlz
  • 3,497
  • 2
  • 23
  • 35