Fixing BeanNotOfRequiredTypeException on Spring proxy cast on a non-singleton bean?
Annotate your @Configuration
class with
@EnableAspectJAutoProxy(proxyTargetClass = true)
You also have to add the following dependency:
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.7.2</version>
</dependency>
Once again, after spending hours trying to debug this I find the answer right after posting on StackOverflow.
A key point that I left out from my question is that InnerThread has a transactional method (sorry thought this was irrelevant). This is the important difference between OuterThread and InnerThread.
From the Spring documentation:
Note
Multiple sections are collapsed into a single unified auto-proxy creator at runtime, which applies the strongest proxy settings that any of the sections (typically from different XML bean definition files) specified. This also applies to the and elements.
To be clear: using 'proxy-target-class="true"' on , or elements will force the use of CGLIB proxies for all three of them.
Adding the above to my configuration (based in persistance-context.xml, which you can see loaded above) line seems to fix the problem. However, I think this may be a quick fix workaround as opposed to real solution.
I think I've got a few deeper issues here, number one being that I find Spring as confusing as expletive deleted. Second I should probably be using Spring's TaskExecutor to kick off my threads. Third my threads should implement Runnable instead of extending Thread (See SO question below).
See Also
- BeanNotOfRequiredTypeException using ServiceLocatorFactoryBean and @Transactional (Nothing better then finding a thread off Google after hours of searching to have a response that says "This has already been answered a million times.")
- Section 6.6 in the Spring Docs.
- Java: “implements Runnable” vs. “extends Thread”
One way to solve this issue is by extending the runnable interface and creating your own:
public interface MyInterface extends Runnable {
// your own method declarations here
void doSomething();
...
}
Then you should implement your interface instead of the runnable:
@Component("myInterface")
@Scope("prototype")
public class MyInterfaceImpl implements MyInterface {
// your own method declarations here
public void doSomething(){
...
}
// implement run from Runnable Interface
@Transactional
public void run(){
.....
}
...
}
This will work fine:
...
MyInterface mynterface = SpringApplicationContext.getBean("myInterface", MyInterface.class);
myInterface.doSomething();
ExecutorService executor = Executors.newSingleThreadExecutor();
executor.submit(myInterface);
...