2017-02-17 9 views
0

Я прочитал более 20 вопросов о stackoverflow, связанных с этим, но ни один из них не работал.Spring @Transactional вызов абстрактного метода суперкласса throws org.hibernate.HibernateException

В принципе, у меня есть абстрактный антресоль службы с 3 методами. Persist похож на шаблонный метод, тогда как сохранение и обновление переопределяются только тогда, когда это необходимо.

public abstract class BaseService<E> implements ServiceImpl{ 
    protected E save(E object, Class<E> returnedClass){//save object} 
    protected E update(E object){//update object} 

    public boolean persist(E object) { 
     //validation rules 

     if(shouldSave) { 
      save(object); 
     }else { 
      update(object); 
     } 
    } 
} 

Тогда я этот подкласс

@Service 
@Transactional 
public CompanyService extends BaseService<Company> { 
    @Autowired 
    private CompanyRepository repository; 

    public void testSaving(Company company) { 
     repository.save(company); 
    } 

    @Override //from service impl 
    public CommpanyRepositoy getRepository() { 
     return repository; 
    } 
} 

и это моя точка

@RestController 
@RequestMapping("/company") 
public CompanyRestController { 
    @Autowired 
    private CompanyService service; 

    @RequestMapping(value = "/save", method = RequestMethod.POST) 
    public boolean save(@RequestBody Company company) { 
     return service.persist(company); 
    } 
} 

записи Теперь дело в том, если я позвоню по методу testSaving, все идет правильно. НО, когда я вызываю метод persist, он всегда дает указанную ошибку. Я пробовал много вещей, таких как добавление @Transactional к суперклассу BaseService, и даже добавление его в мой репозиторий не работает. Пожалуйста, мне нужно это исправить, сводя меня с ума. Любой совет?

org.hibernate.HibernateException: Could not obtain transaction-synchronized Session for current thread 
    at org.springframework.orm.hibernate4.SpringSessionContext.currentSession(SpringSessionContext.java:134) 
    at org.hibernate.internal.SessionFactoryImpl.getCurrentSession(SessionFactoryImpl.java:1014) 
    at br.com.jeffersontpadua.spring.generic.BaseRepository.getSession(BaseRepository.java:56) 
    at br.com.jeffersontpadua.spring.generic.BaseRepository.save(BaseRepository.java:27) 
    at br.com.jeffersontpadua.spring.service.BaseService.save(BaseService.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.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:333) 
    at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190) 
    at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:723) 
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157) 
    at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:655) 
    at br.com.jeffersontpadua.spring.service.CompanyService$$EnhancerBySpringCGLIB$$a3329725.save(<generated>) 
    at br.com.jeffersontpadua.spring.service.BaseService.persist(BaseService.java:34) 
    at br.com.jeffersontpadua.spring.rest.CompanyRestController.save(CompanyRestController.java:41) 
    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:221) 
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:136) 
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:114) 
    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:650) 
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846) 
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:731) 
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303) 
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208) 
    at br.com.jeffersontpadua.spring.filter.RequestFilter.doFilter(RequestFilter.java:34) 
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241) 
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208) 
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) 
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241) 
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208) 
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220) 
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122) 
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:505) 
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:169) 
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103) 
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:956) 
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116) 
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:436) 
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1078) 
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:625) 
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:316) 
    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) 
+1

Когда вы спрашиваете об исключении, ** всегда * * опубликовать полную трассировку стека исключения. –

+0

@JBNizet вопрос обновлен –

ответ

1

Это намеренно, см. SPR-7824.

Вам необходимо разместить аннотацию @Transactional на суперклассе, а не на подклассе, и это приведет к тому, что все методы подкласса будут транзакционными, а также надклассами суперкласса.

Если вы не можете этого сделать, переопределите методы в подклассе и делегируйте их в суперкласс.

+0

Я добавил @Transactional для суперкласса, но даже тогда он не работает. Я думал об основных методах, но я не думаю, что это выглядит красиво. Разве нет другого пути? –

+0

Эй, по какой-то неизвестной причине, переопределяя все методы, участвующие в транзакции и вызывающие суперкласс, заставляет его работать, но это создает множество проблем. Например, теперь любой может переопределить реализацию метода шаблона по умолчанию. У вас есть мысли о том, как заставить его работать без переопределения? –

0

Я, наконец нашел способ, чтобы это произошло, так что, для тех, кто все еще пытается решить эту проблему, хитрость заключается в том, чтобы добавить к вашему @Transactional(propagation = Propagation.REQUIRES_NEW) суперкласса XD

Смежные вопросы