欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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

程序员文章站 2022-03-24 08:17:16
spring jpa 使用@transaction注解时产生cglib代理冲突在使用jpa进行数据库的删除操作时需要使用@transactional注解来支持事物: @modifying @tr...

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。