Announcement Announcement Module
Collapse
No announcement yet.
@Resource on test class field: should work, but still get exception Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • @Resource on test class field: should work, but still get exception

    I'm using Spring 2.5.6 and I need 2 instances of my service ReportService, each with its own data source. Initially got the obvious error from having 2 matching ReportService beans.

    Code:
    org.springframework.beans.factory.NoSuchBeanDefinitionException: No unique bean of type [....ReportService] is defined: expected single matching bean but found 2: [reportService, pdsReportService]
    OK so initially my test class was like this:
    Code:
    public class SiteAppServiceTest extends AbstractUnitTest {
      private SiteAppService siteAppService;
      private ImplementationService implementationService;
      private ReportService reportService;
    
      @Override
      protected String[] getConfigLocations() {
          return new String[]{"appctx-...-service-test.xml"};
      }
    BTW - ReportService is an interface and ReportServiceImpl is listed as the class in the xml. Don't thikn that should matter. The AbstractUnitTest is something my coworker wrote and extends AbstractTransactionalSpringContextTests.

    So I found this page http://static.springsource.org/sprin...e/testing.html and was pretty happy, I just changed my reportService to this:

    Code:
    @Resource(name="reportService")
      private ReportService reportService;
    and I was ready to call it a day. But I reran and got the same exact error. I was stubborn and attached the 2.5.6 source code to my debugger and started stepping through Spring setup itself. After studying some complex code I conclude that although Spring is acknowledging the Resource annotation with the CommonAnnotationBeanPostProcessor doodad and is setting the reportService field on the SiteAppServiceTest, the reportService field is considered unsatisfied and gets shoved into the set of properties that need to be resolved by autowiring.

    My appctx-...-service.test.xml was this

    Code:
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:aop="http://www.springframework.org/schema/aop"
           xmlns:tx="http://www.springframework.org/schema/tx"
           xmlns:context="http://www.springframework.org/schema/context"
           xsi:schemaLocation="http://www.springframework.org/schema/beans
             http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
             http://www.springframework.org/schema/aop
             http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
             http://www.springframework.org/schema/tx
             http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
             http://www.springframework.org/schema/context 
             http://www.springframework.org/schema/context/spring-context-2.5.xsd">
        
      <context:property-placeholder location="file:../../prm/config/test/prm.properties,file:../../prm/config/test/prm-cred.properties.dec,file:../../prm/config/test/cache.ccf,file:../config/test/lemur.properties,file:../config/test/report-cred.properties"/>
    
      <bean id="prmDataSource" class="org.apache.commons.dbcp.BasicDataSource">
       [properties and stuff]
      </bean>
      <bean id="pdsDataSource" class="org.apache.commons.dbcp.BasicDataSource">
      [properties and stuff]
      </bean>
    
      <bean id="prmTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="prmDataSource"/>
      </bean>
    
      <tx:annotation-driven transaction-manager="prmTransactionManager"/>
    
      <!--
        SERVICES
      -->
      <import resource="classpath:appctx-...-service.xml"/>
    
    </beans>
    Code:
    <beans>
    
        <import resource="classpath:appctx-prm-service.xml"/>
    
        <bean id="publisherRegistrationService"
              class="....PublisherRegistrationServiceImpl">
            <property name="publisherService" ref="publisherService"/>
            <property name="propertyService" ref="propertyService"/>
            <property name="contactService" ref="contactService"/>
            <property name="userAccountDAO" ref="userAccountDAO"/>
            <property name="securitySalt" value="${prm.app.salt}"/>
        </bean>
    
    
        <bean id="siteAppService"
              class="...SiteAppServiceImpl">
            <property name="publisherService" ref="publisherService"/>
            <property name="propertyService" ref="propertyService"/>
            <property name="implementationService" ref="implementationService"/>
            <property name="contactService" ref="contactService"/>
            <property name="userAccountDAO" ref="userAccountDAO"/>
            <property name="platformCategoryService" ref="platformCategoryService"/>
        </bean>
    
        <bean id="platformCategoryService" class="....PlatformCategoryServiceImpl">
          <property name="cachingService" ref="cachingService"/>
        </bean>
    
        <bean id="accountService" class="....AccountServiceImpl">
            <property name="publisherService" ref="publisherService"/>
            <property name="contactService" ref="contactService"/>        
        </bean>
    
        <bean id="pdsReportDAO" class="....ReportDAOImpl">
            <property name="dataSource" ref="pdsDataSource"/>
        </bean>
    
        <bean id="pdsReportService" class="....ReportServiceImpl">
            <property name="reportDAO" ref="pdsReportDAO"/>
        </bean>
    
    </beans>
    And I should point out that the beans 'reportService' and 'reportDAO' are further defnined in that included appctx-prm-service.xml file.

    And of course after adding @Resource I added <context:annotation-config /> in the first file.
    Last edited by jpellico; Jan 31st, 2011, 05:01 PM.

  • #2
    Hello

    Be sure to define your beans with unique name to avoid the duplicity error shown, something like @Annotation(name="someName") , where can be @Resource, @Repository, @Service etc, and inject your beans with the @Qualifier annotation

    I suggest you read more documentation about this

    HTH

    Comment


    • #3
      I don't see the second report service defined, but keep in mind that @Resource takes the name of the bean in your config file i.e. @Resource("pdsReportService"). Same goes with using @Qualifier by default (though a different qualifier can be provided).

      Now if the second ReportService instance has an id of "reportService", there's something else at play here...

      Hope this helps
      - Don

      Comment

      Working...
      X