简体   繁体   English

Transactional services => BeanNotOfRequiredTypeException,应该是Advice,但是是TransactionInterceptor

[英]Transactional services => BeanNotOfRequiredTypeException, should be Advice, but is TransactionInterceptor

After following the great advice given in a thread about service beans I have made a Service that is listed under. 在遵循关于服务bean的线程中给出的好建议之后,我已经创建了一个列在其下的服务。 I've tried putting @Transactional at the interface level, interface method level, class level and class method level. 我已经尝试在接口级别,接口方法级别,类级别和类方法级别放置@Transactional。 However I do it, I get 但是我这样做,我明白了

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]

UPDATE: I only get this error when I've defined <tx:annotation-driven transaction-manager="transactionManager/> but I without it, the @Transactional annotation doesn't do anything and I'm left without a Hibernate session. 更新:当我定义了<tx:annotation-driven transaction-manager="transactionManager/>时,我才会收到此错误,但是如果没有它,则@Transactional注释不会执行任何操作,而且我没有进行Hibernate会话。

Any idea why I get this error? 知道为什么我会收到这个错误吗? I'm fairly new to this, but it looks like I'm doing what the PetClinic example is doing, and I've googled around for hours and browsed the docs without getting any wiser. 我对此很陌生,但看起来我正在做PetClinic的例子,我已经搜索了几个小时,浏览了文档而没有更明智。

UPDATE: I've also found a way to config myself into the same error trying to follow suggestions from Abhi On Java . 更新:我还找到了一种方法来将自己配置为同样的错误,试图遵循Abhi On Java的建议。 I've added that all the way in the bottom of this post. 我已经在这篇文章的底部添加了所有内容。

My config, interface and class is listed below. 我的配置,界面和类如下所示。 This is the config that loads the services (UPDATE: What loads the services is in the bottom. The first part is concerning my database and more): 这是加载服务的配置(更新:服务在底部加载什么。第一部分是关于我的数据库和更多):

  <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"/>

This is the interface: 这是界面:

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);
}

and class: 和班级:

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);
    }

}

This is the full exception: 这是完全例外:

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)

Finally, as promised, here is what I can add of configuration to get the exact same exception: 最后,正如所承诺的,这里是我可以添加配置以获得完全相同的异常:

 <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>

This again gives me the following exception: 这再次给了我以下例外:

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

Cheers 干杯

Nik

I think I see the problem now: 我想我现在看到了问题:

... must be of type [org.aopalliance.aop.Advice], but was actually of type [org.springframework.transaction.interceptor.TransactionInterceptor] ...必须是[org.aopalliance.aop.Advice]类型,但实际上是[org.springframework.transaction.interceptor.TransactionInterceptor]类型

Given that TransactionInterceptor is an implementation of org.aopalliance.aop.Advice , this suggests to me that you have a classloading issue. 鉴于TransactionInterceptororg.aopalliance.aop.Advice一个实现,这告诉我你有一个类加载问题。 Specifically, you either have two copies of Spring being loaded by two different classloaders, or two copies of aop-alliance being loaded by two different classloaders. 具体来说,你要么有两个不同的类加载器加载Spring的两个副本,要么由两个不同的类加载器加载两个aop-all的副本。 In this situation, you can get instanceof errors or ClassCastExceptions that can be a bit hard to diagnose. 在这种情况下,您可以获得可能有点难以诊断的instanceof错误或ClassCastExceptions

I suggests looking through your manifests and classpaths, including the app-server's own classpaths, and make sure your application can only find Spring and aop-alliance in one place. 我建议查看您的清单和类路径,包括app-server自己的类路径,并确保您的应用程序只能在一个地方找到Spring和aop-alliance。 Remember that the Spring JARs already include a copy of the aop-alliance stuff, so you don't need another copy. 请记住,Spring JAR已经包含了aop-alliance内容的副本,因此您不需要另一个副本。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM