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 failed
org.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 more
caused 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 more
caused 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 more
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
09-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 file
09-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

对于此异常,这篇帖子中讲到了产生该异常的原因,但是未给出解决办法。

简单来说,原因主要是代理冲突:spring 早期的版本,要用com.sun.proxy的代理 ,而 jpa如果加了@transaction 注解后 需要用cglib的代理

因此产生了冲突

解决办法:

spring 已经在高版本中修复了该问题,把spring从4.0升级到4.2.5后,问题解决:

在pom.xml加入:

<properties>
<spring.framework.version>4.2.5.release</spring.framework.version>
</properties>

spring 启用cglib解决事物代理失败

问题描述:

接口a提供公用的crud 操作,抽象类b实现接口a,接口c提供各模型特有的相关数据库操作。

类d继承抽象类b实现接口c如果使用jdk动态代理,spring会将类d向上转型为接口c,那么在使用中必须注入接口a。

如果注入类d的类型。会报错说代理类型xx无法转换为类d的类型。

解决办法如下:

<bean id="transactionmanagercms"
class="org.springframework.orm.hibernate4.hibernatetransactionmanager">
<property name="sessionfactory" ref="mysessionfactory" />
<property name="datasource" ref="datasourcecms" />
</bean>
<!-- the transactional advice (what 'happens'; see the <aop:advisor/> bean
below) -->
<tx:advice id="txadvice" transaction-manager="transactionmanagercms">
<!-- the transactional semantics... -->
<tx:attributes>
<tx:method name="*" />
</tx:attributes>
</tx:advice>
<!-- ensure that the above transactional advice runs for any execution of
an operation defined by the fooservice interface -->
<aop:config proxy-target-class="true">
<aop:pointcut id="fooserviceoperation"
expression="execution(* com.harvest.smarthotels.info.dao.servicecontent.interfaces.*.*(..))" />
<aop:advisor advice-ref="txadvice" pointcut-ref="fooserviceoperation" />
</aop:config>

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