2009-10-28 42 views
3

在遵循a thread about service beans給出的偉大建議後,我已經提出了一個列在下面的服務。我試着把@Transactional放在界面級別,界面方法級別,類級別和類方法級別。但是我這樣做,我得到Transactional services => BeanNotOfRequiredTypeException,應該是建議,但是TransactionInterceptor

org.springframework.beans.factory.BeanNotOfRequiredTypeException: Bean named 'org.springframework.transaction.interceptor.TransactionInterceptor#0' must be of type [org.aopalliance.aop.Advice], but was actually of type [org.springframework.transaction.interceptor.TransactionInterceptor] 

更新:當我定義<tx:annotation-driven transaction-manager="transactionManager/>但我沒有它,@Transactional註解沒有做任何事情,我留下,不用Hibernate會話我只得到這個錯誤。

任何想法,爲什麼我得到這個錯誤?我對此很新,但看起來我正在做PetClinic的例子,我已經搜索了好幾個小時,瀏覽了文檔,卻沒有明白。

更新:我也找到了一種方法來配置我自己到同一個錯誤,試圖按照Abhi On Java的建議。我已經在這篇文章的底部添加了這些內容。

我的配置,接口和類如下所列。這是一個加載的服務配置(更新:什麼加載的服務是在底部的第一部分是關於我的數據庫和更多):

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"> 
    <property name="driverClassName" value="com.mysql.jdbc.Driver" /> 
    <property name="url"  value="jdbc:mysql://${db.host}:{db.port}/{db.name}" /> 
    <property name="username" value="{db.username}" /> 
    <property name="password" value="{db.password}" /> 
    <property name="initialSize" value="{db.minConnections}" /> 
    <property name="maxActive" value="{db.maxConnections}" /> 
    </bean> 

    <bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean"> 
    <property name="dataSource" ref="dataSource"/> 
    <property name="annotatedClasses"> 
     <list> 
     <value>tld.mydomain.data.entities.User</value> 
     </list> 
    </property> 
    <property name="hibernateProperties"> 
     <props> 
     <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop> 
     <prop key="hibernate.show_sql">false</prop> 
     </props> 
    </property> 
    </bean> 

    <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"> 
    <property name="sessionFactory" ref="sessionFactory"/> 
    </bean> 

    <tx:annotation-driven transaction-manager="transactionManager"/> 

    <bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor"/> 

    <bean name="openSessionInViewInterceptor" class="org.springframework.orm.hibernate3.support.OpenSessionInViewInterceptor"> 
    <property name="sessionFactory" ref="sessionFactory"/> 
    <property name="flushMode" value="0" /> 
    </bean> 

<!-- 

    <bean id="txProxyTemplate" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean" abstract="true"> 
    <property name="transactionManager" ref="transactionManager"/> 
    <property name="transactionAttributes"> 
     <props> 
     <prop key="create*">PROPAGATION_REQUIRED</prop> 
     <prop key="update*">PROPAGATION_REQUIRED</prop> 
     <prop key="delete*">PROPAGATION_REQUIRED</prop> 
     <prop key="*">PROPAGATION_SUPPORTS,readOnly</prop> 
     </props> 
    </property> 
    </bean> 
--> 
    <context:component-scan base-package="tld.mydomain.business"/> 

這是接口:

import org.springframework.security.core.userdetails.UserDetailsService; 
import org.springframework.transaction.annotation.Transactional; 

import tld.mydomain.data.entities.User; 
import tld.mydomain.data.entities.keys.UserId; 

public interface UserService extends UserDetailsService, CRUDService<User, UserId> { 

    @Transactional(readOnly = true) 
    public User lookupUser(String username); 

    @Transactional(readOnly = true) 
    public User publicAliasForUser(String username); 
} 

和類:

import java.util.List; 

import org.hibernate.criterion.Restrictions; 
import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.dao.DataAccessException; 
import org.springframework.security.core.userdetails.UserDetails; 
import org.springframework.security.core.userdetails.UsernameNotFoundException; 
import org.springframework.stereotype.Service; 
import org.springframework.transaction.annotation.Transactional; 

import tld.mydomain.commons.RandomString; 
import tld.mydomain.data.entities.User; 

@Service("userService") 
public class UserServiceImpl extends AbstractCRUDServiceImpl<User, String> implements UserService { 

    @Autowired 
    private LogService logService; 

    @SuppressWarnings("unchecked") 
    @Override 
    public User lookupUser(String username) { 

     if(username == null || username.equals("") || username.equals("anonymousUser")) 
      return null; 

     try { 
      List<User> matchingUsers = (List<User>) DAO.getSession().createCriteria(User.class).add(Restrictions.eq("username", username)).list(); 
      int n = matchingUsers.size(); 
      if(n == 0) return null; 
      if(n > 1) logService.logWarning("Got " + n + " users back, expected just one. Data inconsistency, multiple users with username = " + username); 
      return matchingUsers.get(0); 
     } catch (Exception ex) { 
      logService.logException(ex); 
      return null; 
     } 
    } 

    @Override 
    public UserDetails loadUserByUsername(String username) 
      throws UsernameNotFoundException, DataAccessException { 
     if(username == null || username.equals("") || username.equals("anonymousUser")) 
      return null; 

     User user = this.lookupUser(username); 
     if(user == null) { 
      logService.logWarning("Couldn't find a user to match, throw out a garbage object"); 
      user = new User(); 
      user.setUsername(RandomString.getString(30)); 
      user.setPassword(RandomString.getString(30)); 
     } 

     return user.getUserDetails(); 
    } 

    @SuppressWarnings("unchecked") 
    public User publicAliasForUser(String alias) { 
     List<User> publicUsers = DAO.getSession().createCriteria(User.class) 
     .add(Restrictions.eq("alias", alias)) 
     .list(); 

     if(publicUsers.size() <= 0) return null; 
     if(publicUsers.size() > 1) logService.logWarning("Data inconsistency: More than one alias for a user with alias " + alias); 
     return publicUsers.get(0); 
    } 

} 

這是一個完整的異常:

org.springframework.beans.factory.BeanNotOfRequiredTypeException: Bean named 'org.springframework.transaction.interceptor.TransactionInterceptor#0' must be of type [org.aopalliance.aop.Advice], but was actually of type [org.springframework.transaction.interceptor.TransactionInterceptor] 
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:347) 
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:192) 
    at org.springframework.aop.support.AbstractBeanFactoryPointcutAdvisor.getAdvice(AbstractBeanFactoryPointcutAdvisor.java:77) 
    at org.springframework.aop.framework.adapter.DefaultAdvisorAdapterRegistry.getInterceptors(DefaultAdvisorAdapterRegistry.java:78) 
    at org.springframework.aop.framework.DefaultAdvisorChainFactory.getInterceptorsAndDynamicInterceptionAdvice(DefaultAdvisorChainFactory.java:61) 
    at org.springframework.aop.framework.AdvisedSupport.getInterceptorsAndDynamicInterceptionAdvice(AdvisedSupport.java:481) 
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:188) 
    at $Proxy28.loadUserByUsername(Unknown Source) 
    at org.springframework.security.authentication.dao.DaoAuthenticationProvider.retrieveUser(DaoAuthenticationProvider.java:83) 
    at org.springframework.security.authentication.dao.AbstractUserDetailsAuthenticationProvider.authenticate(AbstractUserDetailsAuthenticationProvider.java:125) 
    at org.springframework.security.authentication.ProviderManager.doAuthentication(ProviderManager.java:121) 
    at org.springframework.security.authentication.AbstractAuthenticationManager.authenticate(AbstractAuthenticationManager.java:49) 
    at org.springframework.security.authentication.ProviderManager.doAuthentication(ProviderManager.java:139) 
    at org.springframework.security.authentication.AbstractAuthenticationManager.authenticate(AbstractAuthenticationManager.java:49) 
    at org.springframework.security.web.authentication.www.BasicAuthenticationFilter.doFilter(BasicAuthenticationFilter.java:142) 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:356) 
    at org.springframework.security.web.authentication.ui.DefaultLoginPageGeneratingFilter.doFilter(DefaultLoginPageGeneratingFilter.java:92) 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:356) 
    at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:188) 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:356) 
    at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:106) 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:356) 
    at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:80) 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:356) 
    at org.springframework.security.web.access.channel.ChannelProcessingFilter.doFilter(ChannelProcessingFilter.java:110) 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:356) 
    at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:150) 
    at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:237) 
    at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:167) 
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235) 
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) 
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233) 
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191) 
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128) 
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102) 
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109) 
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:293) 
    at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:849) 
    at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583) 
    at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:454) 
    at java.lang.Thread.run(Thread.java:637) 

最後,如許,這裏是我可以添加配置來獲得完全相同的例外:

<aop:config> 
    <aop:pointcut id="serviceMethods" expression="execution(* tld.mydomain.business..*(..))" /> 
    <aop:advisor advice-ref="txAdvice" pointcut-ref="serviceMethods" /> 
</aop:config> 

<tx:advice id="txAdvice" transaction-manager="transactionManager" > 
    <tx:attributes> 
    <tx:method name="*" propagation="REQUIRES_NEW" /> 
    </tx:attributes> 
</tx:advice> 

這再次給了我以下異常:

Caused by: org.springframework.beans.factory.BeanNotOfRequiredTypeException: Bean named 'txAdvice' must be of type [org.aopalliance.aop.Advice], but was actually of type [org.springframework.transaction.interceptor.TransactionInterceptor] 
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:347) 
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:192) 
    at org.springframework.aop.support.AbstractBeanFactoryPointcutAdvisor.getAdvice(AbstractBeanFactoryPointcutAdvisor.java:77) 
    at org.springframework.aop.aspectj.AspectJProxyUtils.isAspectJAdvice(AspectJProxyUtils.java:67) 
    at org.springframework.aop.aspectj.AspectJProxyUtils.makeAdvisorChainAspectJCapableIfNecessary(AspectJProxyUtils.java:49) 
    at org.springframework.aop.aspectj.autoproxy.AspectJAwareAdvisorAutoProxyCreator.extendAdvisors(AspectJAwareAdvisorAutoProxyCreator.java:101) 
    at org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator.findEligibleAdvisors(AbstractAdvisorAutoProxyCreator.java:88) 
    at org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator.getAdvicesAndAdvisorsForBean(AbstractAdvisorAutoProxyCreator.java:68) 
    at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.wrapIfNecessary(AbstractAutoProxyCreator.java:359) 
    at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.postProcessAfterInitialization(AbstractAutoProxyCreator.java:322) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsAfterInitialization(AbstractAutowireCapableBeanFactory.java:404) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1401) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:512) 
    ... 26 more 

乾杯

Nik

+0

你有一個抽象的「txProxyTemplate」bean定義,但沒有它的子定義,所以你永遠不會有任何tx代理。你確定這是你擁有它的方式嗎? – skaffman

+0

是的,我注意到並評論了它。這是當我用bean來做bean時的剩餘部分,比如''。但刪除它似乎沒有改變任何東西,我以完全相同的方式得到完全相同的異常 – niklassaers

+0

您發佈的配置中沒有任何內容會導致您的異常。還有其他的東西必須在這裏工作,你還沒有提到。嘗試用顯式的bean定義替換'context:component-scan',看看是否有所作爲。 – skaffman

回答

5

我想我現在看到問題了:

...必須 [org.aopalliance.aop.Advice這個]類型的,但實際上 型 [org.springframework.transaction.interceptor.TransactionInterceptor]

的假設TransactionInterceptor是執行org.aopalliance.aop.Advice,這表明你有一個類加載問題。具體來說,你可以有兩個不同的類加載器加載Spring,或者兩個不同的加載器加載兩個不同的類加載器。在這種情況下,您可能會得到instanceof錯誤或ClassCastExceptions,這可能有點難以診斷。

我建議查看你的清單和類路徑,包括應用程序服務器自己的類路徑,並確保你的應用程序只能在一個地方找到Spring和aop-alliance。請記住,Spring JAR中已經包含了aop-alliance的副本,所以你不需要另外的副本。

+1

謝謝Skaffman,我正在通過我的JAR進程,發現確實存在一些雙倍的結果,包括aopalliance * .jar。我會翻閱所有的東西,拿出我能做的,重新測試並回復你。它可能直到明天才開始,但我對此感覺良好:-)感謝您迄今爲止的所有幫助! :-) – niklassaers

+1

你完全正確,Skaffman。非常感謝你!!! :-) – niklassaers

+1

謝謝Skaffman你是對的! –

相關問題