-
Nothing else really needed. Could the both of you do me a favor and configure
<tx:annotation-driven mode="aspectj"/> ?
and for good measure
<tx:annotation-driven mode="aspectj" transaction-manager="neo4jTransactionManager"/> ?
You know that the proxy tx-mode creates a subclass that is overriding the methods and calls super or a delegate instance with tx-boundaries around that call (at least for classes, uses dynamic proxy for interfaces imho). Perhaps that's somehow messing up the tx-propagation?
MichaelMC could you please summarize your current state, I'm a bit confused by the many dimensions, 2 projects and test + service, too much for my little brain.
Thanks
Michael
-
Hi Michael H.,
Now I have NotInTransactionException in both cases. I'll continue the investigation tomorrow.
Regards,
Daniel
-
By the way, I tried running your tests here, the MemberServiceTest passes, and the MemberServiceImplTest fails with:
org.springframework.beans.factory.BeanCreationExce ption: Error creating bean with name 'com.michael.service.MemberServiceImplTest': Injection of resource dependencies failed; nested exception is org.springframework.beans.factory.NoSuchBeanDefini tionException: No matching bean of type [com.michael.service.MemberServiceImpl] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@javax.annotation.Resource(shareable=true, mappedName=, description=, name=, type=class java.lang.Object, authenticationType=CONTAINER)}
at org.springframework.context.annotation.CommonAnnot ationBeanPostProcessor.postProcessPropertyValues(C ommonAnnotationBeanPostProcessor.java:306)
at org.springframework.beans.factory.support.Abstract AutowireCapableBeanFactory.populateBean(AbstractAu towireCapableBeanFactory.java:1106)
at org.springframework.beans.factory.support.Abstract AutowireCapableBeanFactory.autowireBeanProperties( AbstractAutowireCapableBeanFactory.java:374)
at org.springframework.test.context.support.Dependenc yInjectionTestExecutionListener.injectDependencies (DependencyInjectionTestExecutionListener.java:110 )
at org.springframework.test.context.support.Dependenc yInjectionTestExecutionListener.prepareTestInstanc e(DependencyInjectionTestExecutionListener.java:75 )
at org.springframework.test.context.TestContextManage r.prepareTestInstance(TestContextManager.java:321)
at org.springframework.test.context.junit4.SpringJUni t4ClassRunner.createTest(SpringJUnit4ClassRunner.j ava:211)
at org.springframework.test.context.junit4.SpringJUni t4ClassRunner$1.runReflectiveCall(SpringJUnit4Clas sRunner.java:288)
at org.junit.internal.runners.model.ReflectiveCallabl e.run(ReflectiveCallable.java:15)
at org.springframework.test.context.junit4.SpringJUni t4ClassRunner.methodBlock(SpringJUnit4ClassRunner. java:290)
at org.springframework.test.context.junit4.SpringJUni t4ClassRunner.runChild(SpringJUnit4ClassRunner.jav a:231)
at org.junit.runners.BlockJUnit4ClassRunner.runChild( BlockJUnit4ClassRunner.java:47)
at org.junit.runners.ParentRunner$3.run(ParentRunner. java:231)
at org.junit.runners.ParentRunner$1.schedule(ParentRu nner.java:60)
at org.junit.runners.ParentRunner.runChildren(ParentR unner.java:229)
at org.junit.runners.ParentRunner.access$000(ParentRu nner.java:50)
at org.junit.runners.ParentRunner$2.evaluate(ParentRu nner.java:222)
at org.springframework.test.context.junit4.statements .RunBeforeTestClassCallbacks.evaluate(RunBeforeTes tClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements .RunAfterTestClassCallbacks.evaluate(RunAfterTestC lassCallbacks.java:71)
at org.junit.runners.ParentRunner.run(ParentRunner.ja va:300)
at org.springframework.test.context.junit4.SpringJUni t4ClassRunner.run(SpringJUnit4ClassRunner.java:174 )
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestR eference.run(JUnit4TestReference.java:50)
at org.eclipse.jdt.internal.junit.runner.TestExecutio n.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRu nner.runTests(RemoteTestRunner.java:467)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRu nner.runTests(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRu nner.run(RemoteTestRunner.java:390)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRu nner.main(RemoteTestRunner.java:197)
Caused by: org.springframework.beans.factory.NoSuchBeanDefini tionException: No matching bean of type [com.michael.service.MemberServiceImpl] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@javax.annotation.Resource(shareable=true, mappedName=, description=, name=, type=class java.lang.Object, authenticationType=CONTAINER)}
at org.springframework.beans.factory.support.DefaultL istableBeanFactory.raiseNoSuchBeanDefinitionExcept ion(DefaultListableBeanFactory.java:924)
at org.springframework.beans.factory.support.DefaultL istableBeanFactory.doResolveDependency(DefaultList ableBeanFactory.java:793)
at org.springframework.beans.factory.support.DefaultL istableBeanFactory.resolveDependency(DefaultListab leBeanFactory.java:707)
at org.springframework.context.annotation.CommonAnnot ationBeanPostProcessor.autowireResource(CommonAnno tationBeanPostProcessor.java:438)
at org.springframework.context.annotation.CommonAnnot ationBeanPostProcessor.getResource(CommonAnnotatio nBeanPostProcessor.java:416)
at org.springframework.context.annotation.CommonAnnot ationBeanPostProcessor$ResourceElement.getResource ToInject(CommonAnnotationBeanPostProcessor.java:54 9)
at org.springframework.beans.factory.annotation.Injec tionMetadata$InjectedElement.inject(InjectionMetad ata.java:150)
at org.springframework.beans.factory.annotation.Injec tionMetadata.inject(InjectionMetadata.java:87)
at org.springframework.context.annotation.CommonAnnot ationBeanPostProcessor.postProcessPropertyValues(C ommonAnnotationBeanPostProcessor.java:303)
... 26 more
-
I'm a little busy today but I'll see if I can make the project on GitHub fail with the same errors I was seeing, presumably if you've all got a project you can run and see fail it might make it easier to pinpoint exactly what we've done wrong!
In summary for me, and the case in point here is a single method in a service injected with a repository.:
- Within the method, all calls to my injected repository.save WERE being executed in a transaction
- Within the method, the call to add a relationship to a domain model was NOT being executed in a transaction and threw the relevant exception.
When I browse into the CRUDRepository source code, I notice that the relevant save methods are marked as transactional. I don't know if that means that transactionality was always applying at that level, just not at my service level.
-
Hi All,
Regarding the issue I got related to NotInTransactionException, this was due to component scanning, for those of you using Spring MVC.
The root-context must have the base package defined, excluding controllers:
Code:
<context:component-scan base-package="com.xyz">
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
and the servlet-context must have the appropriate controller subpackage in it, not the root base package.
Code:
<context:component-scan base-package="com.xyz.controller"/>
After changing that, it went through @Transactional code. Hope this will help someone some day. And good job on Spring Data Neo4j project.
Thanks all,
Daniel
-
Oh, thanks a lot Daniel, I did it his way n the demos and samples but didn't realize that it had this impact, could you raise an JIRA issue so that we make sure we add this note to the documentation?
Michael, any luck breaking your GH project ?
-
Thanks for reminding me, just been able to break it now! Try running the refer test in https://github.com/mikeycmccarthy/Sp...eImplTest.java.
Note that I'm not putting any transactional annotations in this test - I'm testing the service and we keep our transaction boundaries there so I want to test that. If you flip the tx type in the test context from aspectj to proxy it works. I don't understand enough about the differences to know what is going on there so I need to read up on that.
-
1 Attachment(s)
Michael,
if you use <tx:annotation-driven mode="aspectj"/> then AJ takes over handling the @Transactional annotations in your code.
You must configure aspectj in your pom to do the class file weaving.
Like so then it works.
Code:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>aspectj-maven-plugin</artifactId>
<version>1.2</version>
<dependencies>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.6.12</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjtools</artifactId>
<version>1.6.12</version>
</dependency>
</dependencies>
<executions>
<execution>
<goals>
<goal>compile</goal>
<goal>test-compile</goal>
</goals>
</execution>
</executions>
<configuration>
<outxml>true</outxml>
<aspectLibraries>
<aspectLibrary>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
</aspectLibrary>
</aspectLibraries>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
You could also configure load-time weaving for your spring context and your app:
Code:
<context:load-time-weaver aspectj-weaving="autodetect"/>
start the JVM with -javaagent:org.springframework.instrument.jar
As your test dirties the database it is sensible to add this to your test-class. Otherwise you have to cleanup the db in the @Before method yourself, so the ctx is re-instantiated for every run.
Code:
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD)
I also attach the file with the diff to your repo.
Attachment 4622
-
Thanks Michael. Makes sense - context is dirtied everytime you are running tests that don't use the spring testing rollback stuff.
I've applied to the project and uploaded, strangely the test still fails though. Was there another commit you meant to make?
Thanks!
-
Michael,
did you apply the changes in all files ?
How does the test fail?
Michael