|
|||||||
![]() |
|
|
Thread Tools | Display Modes |
|
#1
|
|||
|
|||
|
Hi
We have a fully working app using Spring 2.0, and in order to try out some more of the annotation based config, I have been trying to upgrade to 2.1 M3 (and M4). We currently use declarative transaction management for our ORM Repository layer, specified through the @Transactional annotation. Following upgrade, I can not get my existing configuration to work. I have amended references to the XML schemas to use the 2.0 version as per the updated documentation, but continue to get the following exception: Code:
java.lang.IllegalStateException: Property 'transactionManager' must be set on transaction aspect at org.springframework.util.Assert.state(Assert.java:355) at org.springframework.transaction.interceptor.TransactionAspectSupport.createTransactionIfNecessary(TransactionAspectSupport.java:261) at org.springframework.transaction.interceptor.TransactionAspectSupport.createTransactionIfNecessary(TransactionAspectSupport.java:219) at org.springframework.transaction.aspectj.AbstractTransactionAspect.ajc$before$org_springframework_transaction_aspectj_AbstractTransactionAspect$1$2a73e96c(AbstractTransactionAspect.aj:64) at foo.ARepository.fetchAll(ARepository.java:34) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:585) at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:301) at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:182) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:149) at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:106) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171) at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204) at $Proxy9.fetchAll(Unknown Source) at foo.ARepositoryDbUnitTest.testCallNextNo(ARepositoryDbUnitTest.java:79) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:585) at junit.framework.TestCase.runTest(TestCase.java:154) ........ Code:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd">
<bean id="propertyConfigurer" class="org.springframework.web.context.support.ServletContextPropertyPlaceholderConfigurer">
<property name="location"><value>classpath:jdbc.properties</value></property>
<property name="contextOverride"><value>true</value></property>
<property name="systemPropertiesModeName">
<!-- allow system properties to override defaults -->
<value>SYSTEM_PROPERTIES_MODE_OVERRIDE</value>
</property>
</bean>
<bean id="aRepository" class="foo.ARepository" scope="singleton">
<property name="topLinkTemplate"><ref bean="topLinkTemplate"/></property>
</bean>
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName"><value>${jdbc.driverClassName}</value></property>
<property name="url"><value>${jdbc.url}</value></property>
<property name="username"><value>${jdbc.username}</value></property>
<property name="password"><value>${jdbc.password}</value></property>
</bean>
<bean id="sessionFactory" class="org.springframework.orm.toplink.LocalSessionFactoryBean">
<property name="configLocation"><value>testServerSession.xml</value></property>
<property name="sessionName"><value>ATransactions</value></property>
<property name="dataSource"><ref local="dataSource"/></property>
<property name="sessionLog">
<bean class="org.springframework.orm.toplink.support.CommonsLoggingSessionLog"/>
</property>
</bean>
<!-- enable the configuration of transactional behavior based on annotations -->
<tx:annotation-driven transaction-manager="txManager"/>
<bean id="txManager" class="org.springframework.orm.toplink.TopLinkTransactionManager">
<property name="sessionFactory"><ref local="sessionFactory"/></property>
</bean>
<bean id="topLinkTemplate" class="org.springframework.orm.toplink.TopLinkTemplate">
<property name="sessionFactory"><ref bean="sessionFactory"/></property>
</bean>
</beans>
Any ideas on this exception (before I try and create a vanilla test case and JIRA). Many Thanks Marc |
|
#2
|
|||
|
|||
|
Hi
Further information. Within our application we use spring-aspects.jar and @Configurable to dependency inject domain objects using Spring. Although the test case configuration does not configure the AnotationBeanConfigurerAspect (<context:spring-configured/>), our full application does, and therefore this jar is on the classpath for the integration test. If I revert the version of spring-aspects.jar to 2.0, the test runs clean. It appears that there is some form of conflict between the transactional annotation, and spring-aspects. |
|
#3
|
|||
|
|||
|
I'm running into something similar with 2.0.6. From what I understand, if you're using compile-time weaving, adding the @Transactional annotation to a class makes all its public methods match the transactional pointcut, even your dependency setters. When Spring tries to instantiate that class and tries to inject its dependencies by calling the first setter method, it also tries to begin a transaction. Somehow, probably because of the ordering of all these instantiations, the transaction manager isn't ready at that moment.
My current workaround is to remove the @Transactional on the class and use it only on transactional methods. This is far from ideal: you have to repeat your annotation on many methods, as well as the rollback classes. If you find another way, please let me know! |
|
#4
|
|||
|
|||
|
Also it doesn't solve the problem if you're unit testing your @Transactional annotated class, since the application context is not loaded anywhere.
|
|
#5
|
|||
|
|||
|
I've just figured that you can set the transaction manager yourself in those tests that will use @Transactional-annotated classes. Try something like this:
Code:
public class UserServiceImplTest extends TestCase {
@Override
protected void setUp() throws Exception {
PlatformTransactionManager txManager = EasyMock.createMock(PlatformTransactionManager.class);
AnnotationTransactionAspect.aspectOf().setTransactionManager(txManager);
}
}
|
|
#6
|
|||
|
|||
|
Thanks for the info, which reminded me that I had re-packaged the spring-aspects.jar to remove the AnnotationTransactionAspect and AbstractTransactionAspect, to stop this conflict within Spring 2.0. (Doh!)
Can the Spring team advise whether the conflict between using @Transactional using pure Spring, and @Configurable using AspectJ CTW against spring-aspects.jar will be solved (or if there is another solution), without having to resort to hacking the jar file. |
|
#7
|
|||
|
|||
|
Yup, the current workarounds are not that elegant - any input would be greatly appreciated
|
|
#8
|
|||
|
|||
|
I was able to workaround this problem by explicitly configuring the AnnotationTransactionAspect bean.
Code:
<bean class="org.springframework.transaction.aspectj.AnnotationTransactionAspect" factory-method="aspectOf" dependency-check="none">
<property name="transactionManager" ref="transactionManager"/>
</bean>
|
|
#9
|
|||
|
|||
|
This looks like a bug - if you want some input from the Core people the best place to post is on JIRA.
|
|
#10
|
|||
|
|||
|
|
![]() |
| Thread Tools | |
| Display Modes | |
|
|