7

can somebody help for this?

currently i met some problems, i am using spring,jpa,hibernate. here is the problem, when i try to save several objects, and then manually roll back as when solrj return false.

i tried the following:
1. usertransaction (exception: Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException)

2.entitymanager.gettransaction().begin(exception: shared manager)

thanks, if you can help me to figure out.

header:

@Service("jpaWallPostService")
@Repository
public class WallPostServiceImpl implements WallPostService {
    //........
    @PersistenceContext
    private EntityManager em;

======================================

  @Transactional(readOnly=false)
public boolean save(String solrURL,int userid,wall_post wallPost,List<String> groupsid,List<String> hashtag){


    try{
        em.getTransaction().begin();// ***error occur on here*** and stop here
        //...............proccess
        boolean ok = SolrJ.IndexingWallPost(solrURL,userid, wallPost.getTitle(), wallPost.getMessage(), hashtag,groupsid);
        if(!ok)
            em.getTransaction().rollback();



        em.getTransaction().commit();
        return true;
    }
    catch(Exception e)
    {
        em.getTransaction().rollback();
        return false;
    }
}

here is the error log

SEVERE: Servlet.service() for servlet [appServlet] in context with path [/opscentral] threw exception [Request processing failed; nested exception is java.lang.IllegalStateException: Not allowed to create transaction on shared EntityManager - use Spring transactions or EJB CMT instead] with root cause
java.lang.IllegalStateException: Not allowed to create transaction on shared EntityManager - use Spring transactions or EJB CMT instead
    at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:198)
    at $Proxy42.getTransaction(Unknown Source)
    at sg.com.innovax.opscentralv5.table.service.impl.WallPostServiceImpl.save(WallPostServiceImpl.java:230)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:601)
    at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:319)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:183)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:110)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
    at $Proxy49.save(Unknown Source)
    at sg.com.innovax.opscentralv5.UserHomeController.newWall_post(UserHomeController.java:171)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:601)
    at org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:213)
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:126)
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:96)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:617)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:578)
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:80)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:923)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:852)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:882)
    at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:789)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:647)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:311)
    at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:116)
    at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:83)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323)
    at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:113)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323)
    at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:101)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323)
    at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:113)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323)
    at org.springframework.security.web.authentication.rememberme.RememberMeAuthenticationFilter.doFilter(RememberMeAuthenticationFilter.java:146)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323)
    at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:54)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323)
    at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:45)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323)
    at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:182)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323)
    at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:105)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323)
    at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:87)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323)
    at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:173)
    at org.springframework.security.config.debug.DebugFilter.doFilterInternal(DebugFilter.java:45)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)
    at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346)
    at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:259)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:947)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1009)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:589)
    at org.apache.tomcat.util.net.AprEndpoint$SocketProcessor.run(AprEndpoint.java:1852)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
    at java.lang.Thread.run(Thread.java:722)
Stupidfrog
  • 2,042
  • 6
  • 25
  • 35

2 Answers2

12

Proper way is to remove all manual transaction management when using the @Transactional. In a proper CMT context you shouldn't manually interact with transactions, the @transactional ensure that your method will run inside a transaction, will propagate the transaction context to delegate call and will commit at the end of execution or rollback in case of exception thrown. The only things you may do is to force rollback using setRollbackOnly() on the EJBContext

See : is there a way to force a transactional rollback without encountering an exception?

Otherwise if you prefer to manually manage the transaction :

Define a transactionManager bean in your spring context using your entityManagerFactory.

 <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
    <property name="entityManagerFactory" ref="entityManagerFactory" />
 </bean>

and use it this way :

@Inject
JpaTransactionManager txManager;

DefaultTransactionDefinition def = new DefaultTransactionDefinition();
def.setName("rootTransaction");
def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
TransactionStatus status = txManager.getTransaction(def);
[...]
txManager.commit(status);
Community
  • 1
  • 1
Gab
  • 7,869
  • 4
  • 37
  • 68
  • i did set the transactionmanager originally.... and not even start, then error.So the rest of the code wont run after error prompt – Stupidfrog Apr 03 '13 at 08:25
  • How do you manage annotation handling so ? Don't you have something like this : – Gab Apr 03 '13 at 08:34
  • And so ? If you inject transactionManager in your bean and call .commit() on it what's going wrong ? – Gab Apr 03 '13 at 08:56
  • the error on original post---(Not allowed to create transaction on shared EntityManager - use Spring transactions or EJB CMT instead) – Stupidfrog Apr 03 '13 at 09:16
  • First---Gab, you are so helpful, thanks :) just now i tried throw RuntimeException, it work, it roll back the records. previously doesn't work, it beacause of i do try and catch thefore the exception already consumed. however, although it work(by throwing exception),but i dont think it is a good idea and proper way to do it. And i will try your way now :) – Stupidfrog Apr 03 '13 at 09:29
  • Of course it works and yes to let the exception propagate to rollback the transaction is the proper way to go if you are using container managed transaction, (the @transactional annotation), the other way i gave you is just a messy work-around – Gab Apr 03 '13 at 09:33
  • Are you saying by using throw exception is a proper way? and you edited version is work! thanks! – Stupidfrog Apr 03 '13 at 09:43
  • @Stupidfrog : Don't manually throw an exception, if there is one, let it propagate to trigger the rollback, otherwise use `EJBContext.setRollBackOnly()` (see edition) – Gab Apr 03 '13 at 09:53
3

The problem is that your save method is annotated Transactional which means that the transaction would be handled by Spring, but within the method you are trying to manage transaction programatically using the JPA API.

So you are wrongly mixing two approaches. Ideally you should use only the Transactional annotation.

Below I have added the source code from the Spring helper classes which handles this. The relevant class is org.springframework.orm.jpa.SharedEntityManagerCreator.It has a private static class SharedEntityManagerInvocationHandler and the relevant code where the error is thrown is below

public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
  .....
  .....
  else if (method.getName().equals("getTransaction")) {
      throw new IllegalStateException("Not allowed to create transaction on shared"
                             +" EntityManager - use Spring transactions or EJB CMT instead");
.....
.....
  }

So this is what I mentioned above.

You are calling getTransaction method and you are getting the error.

So get rid of the transaction handling inside the method and stick only to the Transactional annotation.

Shailendra
  • 8,874
  • 2
  • 28
  • 37
  • True, and your method body should look like this `boolean ok = SolrJ.IndexingWallPost(solrURL,userid, wallPost.getTitle(), wallPost.getMessage(), hashtag,groupsid); if(!ok) // throw some RuntimeException; ` – Ori Dar Apr 03 '13 at 08:56
  • i agree with your points based on my research and understanding. i guessing the spring is occupy the transaction and i try to get and control it. However i just remove the @Transactional and try to get transaction, then i met this problems ("java.lang.IllegalStateException: Not allowed to create transaction on shared EntityManager - use Spring transactions or EJB CMT instead") – Stupidfrog Apr 03 '13 at 09:01
  • orid---your method is work, but just to be sure no try and catch within this area, else will have same problems with me.thanks! – Stupidfrog Apr 03 '13 at 09:45