#java #spring #hibernate #spring-transactions #transactional
#java #spring #спящий режим #spring-транзакции #транзакционный
Вопрос:
Я сталкиваюсь с этим исключением TransactionRequiredException, даже когда, по-видимому, был применен перехватчик транзакций:
javax.persistence.TransactionRequiredException: no transaction is in progress
at org.hibernate.internal.SessionImpl.checkTransactionNeeded(SessionImpl.java:3393)
at org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1386)
at org.springframework.orm.hibernate5.SessionFactoryUtils.flush(SessionFactoryUtils.java:144)
at org.springframework.orm.hibernate5.SpringSessionSynchronization.beforeCommit(SpringSessionSynchronization.java:95)
at org.springframework.transaction.support.TransactionSynchronizationUtils.triggerBeforeCommit(TransactionSynchronizationUtils.java:95)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.triggerBeforeCommit(AbstractPlatformTransactionManager.java:932)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:744)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:730)
at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:487)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:291)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:655)
at my.pkg.entity.impl.StoreImpl$EnhancerBySpringCGLIB$73283c3f.merge(<generated>)
at my.pkg.controller.LoginController.setClient(LoginController.java:243)
at my.pkg.controller.LoginController.setupUserSession(LoginController.java:185)
at my.pkg.controller.LoginController.login(LoginController.java:121)
at my.pkg.controller.LoginController$FastClassBySpringCGLIB$d71b2e05.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:651)
at my.pkg.controller.LoginController$EnhancerBySpringCGLIB$442b15b7.login(<generated>)
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:497)
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)
............
Вот что я использую:
Hibernate-5.2 (hibernate-entitymanager-5.1, hibernate-commons-annotations-5.0.1)
Spring-4.3.3 - (tried 4.3.2 as well, same error)
Мой диспетчер <сервлет> -servlet.xml пусто, и вся конфигурация spring находится в applicationContext.xml:
<context:annotation-config />
<context:component-scan base-package="my.pkg.controller, my.pkg.entity"></context:component-scan>
<mvc:annotation-driven enable-matrix-variables="true" content-negotiation-manager="contentNegotiationManager" />
<import resource="db-config.xml" />
db-config.xml имеет:
<bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource"></property>
<property name="mappingResources">
<list>
<value>.......hbm.xml</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.connection.autocommit">false</prop>
<prop key="current_session_context_class">thread</prop >
</props>
</property>
</bean>
<bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource" destroy-method="close">
.......
</bean>
<bean id="transactionManager" class="org.springframework.orm.hibernate5.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<tx:advice id="transactionalAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="get*" read-only="true"/>
<tx:method name="find*" read-only="true"/>
<tx:method name="*" />
</tx:attributes>
</tx:advice>
<aop:config>
<!-- applying this aop on other job classes -->
</aop:config>
<tx:advice id="traxSupportedAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="*" propagation="SUPPORTS" />
</tx:attributes>
</tx:advice>
<aop:config>
<aop:advisor pointcut="execution(* my.pkg.entity.*Home.*(..))" advice-ref="traxSupportedAdvice" />
</aop:config>
Мои классы my.pkg.entity.impl. * Impl расширяются из my.pkg.entity.* Домашние классы (я использую инструменты jboss для автоматической генерации домашних классов <entity> и <entity> ), и все * классы Impl (не *Домашние классы) также помечены @Transactional . * Home указаны в aop с рекомендациями по распространению «Поддерживает».
LoginController.setClient() помечается символом @Transactional .
Я не могу понять, что я делаю неправильно или не хватает. Я пытался выполнить поиск в SOF и в Google, но не смог найти то, что можно было бы применить здесь.
Дайте мне знать, если требуется какая-либо другая информация. Пожалуйста, также дайте мне знать, если я отклоняюсь от какого-либо стандартного / предпочтительного подхода к настройке здесь.
Спасибо за вашу помощь.
Ответ №1:
Аннотация @Transactional для LoginController.setClient не применяется. Потому что это внутренний вызов bean. Вы видите это в трассировке стека
at my.pkg.controller.LoginController.setClient(LoginController.java:243)
at my.pkg.controller.LoginController.setupUserSession(LoginController.java:185)
at my.pkg.controller.LoginController.login(LoginController.java:121)
Возможно, вы можете запустить его с помощью метода входа в систему. Но у меня недостаточно подробностей, чтобы рассказать.