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

 更新时间:2021年08月04日 15:59:29   作者:hikeboy  
这篇文章主要介绍了解决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 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

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

http://stackoverflow.com/questions/20063320/springmvc-proxy-issue

简单来说,原因主要是代理冲突: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。

相关文章

  • Springmvc数据回显实现原理实例解析

    Springmvc数据回显实现原理实例解析

    这篇文章主要介绍了Springmvc数据回显实现原理实例解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-09-09
  • MyBatis实现简单的数据表分月存储

    MyBatis实现简单的数据表分月存储

    本文主要介绍了MyBatis实现简单的数据表分月存储,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-03-03
  • 浅谈PrintStream和PrintWriter的区别和联系

    浅谈PrintStream和PrintWriter的区别和联系

    这篇文章主要介绍了浅谈PrintStream和PrintWriter的区别和联系,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-03-03
  • Java StringBuilder类原理及常用方法

    Java StringBuilder类原理及常用方法

    这篇文章主要介绍了Java StringBuilder类原理及常用方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-12-12
  • java多线程之Phaser的使用详解

    java多线程之Phaser的使用详解

    这篇文章主要介绍了java多线程之Phaser的使用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-03-03
  • python实现高斯模糊及原理详解

    python实现高斯模糊及原理详解

    高斯模糊是一种常见的模糊技术,本文主要介绍了python实现高斯模糊及原理详解,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-05-05
  • java 如何给对象中的包装类设置默认值

    java 如何给对象中的包装类设置默认值

    这篇文章主要介绍了java 如何给对象中的包装类设置默认值,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-03-03
  • Java基础之static关键字的使用讲解

    Java基础之static关键字的使用讲解

    这篇文章主要介绍了Java基础之static关键字的使用讲解,本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下
    2021-07-07
  • SpringBoot整合jasypt进行重要数据加密的操作代码

    SpringBoot整合jasypt进行重要数据加密的操作代码

    Jasypt(Java Simplified Encryption)是一个专注于简化Java加密操作的开源工具,它提供了一种简单而强大的方式来处理数据的加密和解密,使开发者能够轻松地保护应用程序中的敏感信息,本文给大家介绍了SpringBoot整合jasypt进行重要数据加密,需要的朋友可以参考下
    2024-05-05
  • Spring注解@Configuration和@Component区别详解

    Spring注解@Configuration和@Component区别详解

    @Component和@Configuration都可以作为配置类,之前一直都没觉得这两个用起来有什么差别,可能有时程序跑的和自己想的有所区别也没注意到,下面这篇文章主要给大家介绍了关于Spring注解@Configuration和@Component区别的相关资料,需要的朋友可以参考下
    2023-04-04

最新评论