解决Spring|解决Spring JPA 使用@transaction注解时产生CGLIB代理冲突问题

Spring JPA 使用@transaction注解时产生CGLIB代理冲突 在使用JPA进行数据库的删除操作时需要使用@Transactional注解来支持事物:

@Modifying@Transactional@Query(" delete from FollowerInfo " +" where crmAuth = :crmAuth and investUserId = :invUserId")void deleteByCrmAuthAndInvUserId(@Param("crmAuth") String crmAuth, @Param("invUserId") Long invUserId);

但是,在添加了如上方法后,测试服务启动失败。
查看日志报错如下:
Caused by: java.lang.IllegalArgumentException: Cannot subclass final class class com.sun.proxy.$Proxy52 at org.springframework.cglib.proxy.Enhancer.generateClass(Enhancer.java:446) at org.springframework.cglib.transform.TransformingClassGenerator.generateClass(TransformingClassGenerator.java:33) at org.springframework.cglib.core.DefaultGeneratorStrategy.generate(DefaultGeneratorStrategy.java:25) at org.springframework.cglib.core.AbstractClassGenerator.create(AbstractClassGenerator.java:216) at org.springframework.cglib.proxy.Enhancer.createHelper(Enhancer.java:377) at org.springframework.cglib.proxy.Enhancer.createClass(Enhancer.java:317) at org.springframework.aop.framework.ObjenesisCglibAopProxy.createProxyClassAndInstance(ObjenesisCglibAopProxy.java:57) at org.springframework.aop.framework.CglibAopProxy.getProxy(CglibAopProxy.java:202) ... 38 more[2017-02-09 10:56:33 ERROR] [localhost-startStop-1] (org.springframework.web.context.ContextLoader:331) - Context initialization failedorg.springframework.beans.factory.BeanCreationException: Error creating bean with name 'adviserCommFollowerServiceImpl': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.ounersc.ic.adviser.repository.community.AdviserCommFollowerRepository com.ounersc.ic.adviser.service.impl.AdviserCommFollowerServiceImpl.adviserCommFollowerRepository; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'adviserCommFollowerRepository': Post-processing of FactoryBean's singleton object failed; nested exception is org.springframework.aop.framework.AopConfigException: Could not generate CGLIB subclass of class [class com.sun.proxy.$Proxy52]: Common causes of this problem include using a final class or a non-visible class; nested exception is java.lang.IllegalArgumentException: Cannot subclass final class class com.sun.proxy.$Proxy52 at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:334) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1204) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:538) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476) at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:302) at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:229) at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:298) at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193) at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:725) at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:757) at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:480) at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:403) at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:306) at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:106) at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4738) at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5181) at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150) at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1408) at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1398) at java.util.concurrent.FutureTask.run(FutureTask.java:262) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) at java.lang.Thread.run(Thread.java:745)Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.ounersc.ic.adviser.repository.community.AdviserCommFollowerRepository com.ounersc.ic.adviser.service.impl.AdviserCommFollowerServiceImpl.adviserCommFollowerRepository; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'adviserCommFollowerRepository': Post-processing of FactoryBean's singleton object failed; nested exception is org.springframework.aop.framework.AopConfigException: Could not generate CGLIB subclass of class [class com.sun.proxy.$Proxy52]: Common causes of this problem include using a final class or a non-visible class; nested exception is java.lang.IllegalArgumentException: Cannot subclass final class class com.sun.proxy.$Proxy52 at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:555) at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87) at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:331) ... 22 moreCaused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'adviserCommFollowerRepository': Post-processing of FactoryBean's singleton object failed; nested exception is org.springframework.aop.framework.AopConfigException: Could not generate CGLIB subclass of class [class com.sun.proxy.$Proxy52]: Common causes of this problem include using a final class or a non-visible class; nested exception is java.lang.IllegalArgumentException: Cannot subclass final class class com.sun.proxy.$Proxy52 at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.getObjectFromFactoryBean(FactoryBeanRegistrySupport.java:116) at org.springframework.beans.factory.support.AbstractBeanFactory.getObjectForBeanInstance(AbstractBeanFactory.java:1512) at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:313) at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193) at org.springframework.beans.factory.support.DefaultListableBeanFactory.findAutowireCandidates(DefaultListableBeanFactory.java:1081) at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1006) at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:904) at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:527) ... 24 moreCaused by: org.springframework.aop.framework.AopConfigException: Could not generate CGLIB subclass of class [class com.sun.proxy.$Proxy52]: Common causes of this problem include using a final class or a non-visible class; nested exception is java.lang.IllegalArgumentException: Cannot subclass final class class com.sun.proxy.$Proxy52 at org.springframework.aop.framework.CglibAopProxy.getProxy(CglibAopProxy.java:212) at org.springframework.aop.framework.ProxyFactory.getProxy(ProxyFactory.java:109) at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.createProxy(AbstractAutoProxyCreator.java:445) at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.wrapIfNecessary(AbstractAutoProxyCreator.java:331) at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.postProcessAfterInitialization(AbstractAutoProxyCreator.java:291) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsAfterInitialization(AbstractAutowireCapableBeanFactory.java:422) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.postProcessObjectFromFactoryBean(AbstractAutowireCapableBeanFactory.java:1713) at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.getObjectFromFactoryBean(FactoryBeanRegistrySupport.java:113) ... 31 moreCaused by: java.lang.IllegalArgumentException: Cannot subclass final class class com.sun.proxy.$Proxy52 at org.springframework.cglib.proxy.Enhancer.generateClass(Enhancer.java:446) at org.springframework.cglib.transform.TransformingClassGenerator.generateClass(TransformingClassGenerator.java:33) at org.springframework.cglib.core.DefaultGeneratorStrategy.generate(DefaultGeneratorStrategy.java:25) at org.springframework.cglib.core.AbstractClassGenerator.create(AbstractClassGenerator.java:216) at org.springframework.cglib.proxy.Enhancer.createHelper(Enhancer.java:377) at org.springframework.cglib.proxy.Enhancer.createClass(Enhancer.java:317) at org.springframework.aop.framework.ObjenesisCglibAopProxy.createProxyClassAndInstance(ObjenesisCglibAopProxy.java:57) at org.springframework.aop.framework.CglibAopProxy.getProxy(CglibAopProxy.java:202) ... 38 more09-Feb-2017 10:56:33.145 SEVERE [localhost-startStop-1] org.apache.catalina.core.StandardContext.startInternal One or more listeners failed to start. Full details will be found in the appropriate container log file09-Feb-2017 10:56:33.145 SEVERE [localhost-startStop-1] org.apache.catalina.core.StandardContext.startInternal Context [] startup failed due to previous errors

org.springframework.aop.framework.AopConfigException: Could not generate CGLIB subclass of class [class com.sun.proxy.$Proxy52]: Common causes of this problem include using a final class or a non-visible class
对于此异常,这篇帖子中讲到了产生该异常的原因,但是未给出解决办法。
http://stackoverflow.com/questions/20063320/springmvc-proxy-issue
简单来说,原因主要是代理冲突:Spring 早期的版本,要用com.sun.proxy的代理 ,而 jpa如果加了@transaction 注解后 需要用CGLIB的代理
因此产生了冲突
解决办法:
【解决Spring|解决Spring JPA 使用@transaction注解时产生CGLIB代理冲突问题】Spring 已经在高版本中修复了该问题,把Spring从4.0升级到4.2.5后,问题解决:
在pom.xml加入:
4.2.5.RELEASE

Spring 启用CGLIB解决事物代理失败 问题描述:
接口A提供公用的CRUD 操作,抽象类B实现接口A,接口C提供各模型特有的相关数据库操作。
类D继承抽象类B实现接口C如果使用JDK动态代理,Spring会将类D向上转型为接口C,那么在使用中必须注入接口A。
如果注入类D的类型。会报错说代理类型XX无法转换为类D的类型。
解决办法如下:

动态代理使用CGLIB,这样注入类型就可以使类D。

    推荐阅读