2012-07-31 92 views
0

我想將現有Spring 3 JPA 2 Hibernate Web應用程序遷移到Spring Data JPA。 然而只是加入最新的Spring數據JPA的Maven項目和配置Spring數據如下Spring Data JPA強制CGLib代理到非存儲庫類

<jpa:repositories 
    base-package="myapp.persistence.spring" 
    entity-manager-factory-ref="entityManagerFactory" 
    transaction-manager-ref="transactionManager" /> 

春天開始抱怨:

2012-07-31 16:54:23,153 ERROR [ContextLoader  ] - [Context initialization failed                  ] - [remoteAddress=, remoteHost=, thread=pool-2-thread-1] org.springframework.web.context.ContextLoader 
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'companyRepository' defined in file [C:\Development\ApplicationServer\apache-tomcat-7.0.27\webapps\myapp\WEB-INF\classes\myapp\persistence\CompanyRepository.class]: Initialization of bean failed; nested exception is org.springframework.aop.framework.AopConfigException: Cannot proxy target class because CGLIB2 is not available. Add CGLIB to the class path or specify proxy interfaces. 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:527) ~[spring-beans-3.1.2.RELEASE.jar:3.1.2.RELEASE] 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456) ~[spring-beans-3.1.2.RELEASE.jar:3.1.2.RELEASE] 
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:294) ~[spring-beans-3.1.2.RELEASE.jar:3.1.2.RELEASE] 
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:225) ~[spring-beans-3.1.2.RELEASE.jar:3.1.2.RELEASE] 
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:291) ~[spring-beans-3.1.2.RELEASE.jar:3.1.2.RELEASE] 
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193) ~[spring-beans-3.1.2.RELEASE.jar:3.1.2.RELEASE] 
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:609) ~[spring-beans-3.1.2.RELEASE.jar:3.1.2.RELEASE] 
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:918) ~[spring-context-3.1.2.RELEASE.jar:3.1.2.RELEASE] 
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:469) ~[spring-context-3.1.2.RELEASE.jar:3.1.2.RELEASE] 
    at org.springframework.web.context.ContextLoader.createWebApplicationContext(ContextLoader.java:282) ~[spring-web-3.0.7.RELEASE.jar:3.0.7.RELEASE] 
    at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:204) ~[spring-web-3.0.7.RELEASE.jar:3.0.7.RELEASE] 
    at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:47) [spring-web-3.0.7.RELEASE.jar:3.0.7.RELEASE] 
    at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4779) [catalina.jar:7.0.27] 
    at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5273) [catalina.jar:7.0.27] 
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150) [catalina.jar:7.0.27] 
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1566) [catalina.jar:7.0.27] 
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1556) [catalina.jar:7.0.27] 
    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303) [na:1.6.0_24] 
    at java.util.concurrent.FutureTask.run(FutureTask.java:138) [na:1.6.0_24] 
    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886) [na:1.6.0_24] 
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908) [na:1.6.0_24] 
    at java.lang.Thread.run(Thread.java:662) [na:1.6.0_24] 
Caused by: org.springframework.aop.framework.AopConfigException: Cannot proxy target class because CGLIB2 is not available. Add CGLIB to the class path or specify proxy interfaces. 
    at org.springframework.aop.framework.DefaultAopProxyFactory.createAopProxy(DefaultAopProxyFactory.java:67) ~[spring-aop-3.1.2.RELEASE.jar:3.1.2.RELEASE] 
    at org.springframework.aop.framework.ProxyCreatorSupport.createAopProxy(ProxyCreatorSupport.java:104) ~[spring-aop-3.1.2.RELEASE.jar:3.1.2.RELEASE] 
    at org.springframework.aop.framework.ProxyFactory.getProxy(ProxyFactory.java:112) ~[spring-aop-3.1.2.RELEASE.jar:3.1.2.RELEASE] 
    at org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor.postProcessAfterInitialization(PersistenceExceptionTranslationPostProcessor.java:133) ~[spring-tx-3.1.2.RELEASE.jar:3.1.2.RELEASE] 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsAfterInitialization(AbstractAutowireCapableBeanFactory.java:407) ~[spring-beans-3.1.2.RELEASE.jar:3.1.2.RELEASE] 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1461) ~[spring-beans-3.1.2.RELEASE.jar:3.1.2.RELEASE] 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:519) ~[spring-beans-3.1.2.RELEASE.jar:3.1.2.RELEASE] 
    ... 21 common frames omitted 

注意,春季數據配置爲掃描包myapp.persistence.spring而上面的錯誤引用了包myapp.persistence中的一個類。當我將CGlib添加到項目中時,包括Spring Data在內的所有工作都很好。但是發生了什麼?我是一名春季新秀,頗感迷惑。我無法弄清楚Spring Data如何成爲代理魔術。至少官方的例子根本不包括CGlib。進一步的信息:

CompanyRepository是一個簡單的自制JPA-DAO使用的EntityManager:

@Repository 
@Transactional(propagation = Propagation.MANDATORY) 
public class CompanyRepository extends AbstractRepository<Company, Long> { 
    … 
} 

交易經由@Transactional啓用和AspectJ編譯時織入。語境配置片段:

<tx:annotation-driven proxy-target-class="true" mode="aspectj"/> 
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"> 
    <property name="entityManagerFactory" ref="entityManagerFactory" /> 
</bean> 

部署到Tomcat 7.0.27

回答

2

由於使用<jpa:repositories />reference documentation描述激活持續異常轉換與@Repository註解的Spring bean。從@RepositoryJavaDoc開始,註釋的主要目的是異常轉換,將應用於註釋的組件。如果您的類實現了一個接口,則可以使用普通的JDK代理。如果沒有 - 就像你的情況一樣 - CGLib需要創建代理。更多細節請見Spring reference documentation

要使用<jpa:repositories />沒有CGLIB你基本上是在你的情況下兩種選擇:

  1. 介紹與@Repository標註的每個組件的接口。這仍然會應用持久性異常翻譯,這可能是你想要的。
  2. 首先不使用@Repository,而是使用@Component實質上禁用這些組件的異常轉換。
相關問題