Announcement Announcement Module
Collapse
No announcement yet.
Problem with AbstractTransactionalDataSourceSpringContextTes Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Problem with AbstractTransactionalDataSourceSpringContextTes

    I keep getting this error , when trying to unit test my service.

    my applicationContext.xml

    Code:
    <bean id="rssService"  class="org.springframework.aop.framework.ProxyFactoryBean">
        	<!-- define target of proxy-->
        	<property name="target">
        		<ref local ="rssServiceTarget"/>
        	</property>
            <property name="proxyInterfaces">
               <value>com.vanitysoft.griffin.service.rss.IRSSService</value>
             </property>
             <property name="interceptorNames">
               <list>
                  <value>hibernateInterceptor</value>
                  <value>cacheInterceptor</value>
               </list>
             </property>	
        </bean>  
     
          <bean id="rssServiceTarget"  class="com.vanitysoft.griffin.service.rss.impl.RSSServiceImpl" >          
         	<property name="channelDAO">
    			<ref bean="channelDAO"/>
    		</property>
     	 <property name="rssExtensionDAO">
    			<ref bean="rssExtensionDAO"/>
    		</property>
    	 <property name="persistenceManager">
    			<ref bean="persistenceManagerHibernate"/>
    		</property>	
    	 <property name="cacheProvider">
    			<ref bean="cacheProvider"/>
    		</property>
    			 <property name="translationService">
    			<ref bean="translationService"/>
    		</property>
    	  <property name="scheduler">
    			<ref bean="scheduler"/>
    		</property>
    		<property name="poller"><ref bean="poller"/></property>
         </bean>

    I am setting my Unit test up correctly im sure..
    Code:
    package com.vanitysoft.griffin.service.rss.impl;
    
    import org.quartz.Scheduler;
    import org.springframework.test.AbstractTransactionalDataSourceSpringContextTests;
    
    import com.vanitysoft.griffin.service.rss.IRSSService;
    
    import de.nava.informa.utils.manager.PersistenceManagerIF;
    
    public abstract class AbstractServiceTest 
    extends AbstractTransactionalDataSourceSpringContextTests&#123;
    
     protected IRSSService rssService = null;
    
    public void setRssService&#40;IRSSService rssService&#41; &#123;
    	this.rssService = rssService;
    &#125;
    &#125;

    my unit test that extends the above class.

    Code:
    public class RSSServiceTest
        extends AbstractServiceTest
    &#123;
        //~ Static fields/initializers ---------------------------------------------
    
    
        //~ Instance fields --------------------------------------------------------
    
        Logger logger = Logger.getLogger&#40; RSSServiceTest.class &#41;;
    
        //~ Constructors -----------------------------------------------------------
    
    
        //~ Methods ----------------------------------------------------------------
    
    
        public void  testConvert&#40;  &#41;
        &#123;
    
        rssService.doStuff&#40;&#41;;
        &#125;




    my error is this,
    Code:
    org.springframework.beans.factory.UnsatisfiedDependencyException&#58; Error creating bean with name 'com.vanitysoft.griffin.service.rss.impl.RSSServiceTest' defined in null&#58; Unsatisfied dependency expressed through bean property 'rssService'&#58; There are 4 beans of type &#91;interface com.vanitysoft.griffin.service.rss.IRSSService&#93; for autowire by type. There should have been 1 to be able to autowire property 'rssService' of bean 'com.vanitysoft.griffin.service.rss.impl.RSSServiceTest'.
    	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireByType&#40;AbstractAutowireCapableBeanFactory.java&#58;800&#41;
    	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean&#40;AbstractAutowireCapableBeanFactory.java&#58;720&#41;
    	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireBeanProperties&#40;AbstractAutowireCapableBeanFactory.java&#58;188&#41;
    	at org.springframework.test.AbstractDependencyInjectionSpringContextTests.setUp&#40;AbstractDependencyInjectionSpringContextTests.java&#58;141&#41;
    	at junit.framework.TestCase.runBare&#40;TestCase.java&#58;125&#41;
    	at junit.framework.TestResult$1.protect&#40;TestResult.java&#58;106&#41;
    	at junit.framework.TestResult.runProtected&#40;TestResult.java&#58;124&#41;
    	at junit.framework.TestResult.run&#40;TestResult.java&#58;109&#41;
    	at junit.framework.TestCase.run&#40;TestCase.java&#58;118&#41;
    	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests&#40;RemoteTestRunner.java&#58;478&#41;
    	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run&#40;RemoteTestRunner.java&#58;344&#41;
    	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main&#40;RemoteTestRunner.java&#58;196&#41;

  • #2
    By default the unit test context support tries to do autowiring by type. Read the reference docs, javadocs and maybe take a look at the source to see how you bypass this.
    (btw, the app context you showed doesn't contain the RSSServiceTest)

    Comment


    • #3
      that was my point in posting on how to do it, because i did not find it in the docs...

      I am testing rssService , not RssServiceTest, i would not have it autowired.

      Comment


      • #4
        make sure that the application context that you load when doing the test contains only one type of IRSSService.

        Comment


        • #5
          my entire applicationContext.xml

          Code:
          <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http&#58;//www.springframework.org/dtd/spring-beans.dtd">
          <beans> 
              <import resource="daoContext.xml"/>  
              
              <!-- Define the method interceptor advice. -->
             
              <bean id="exceptionInterceptorAdvice"  class="com.vanitysoft.griffin.service.util.ExceptionInterceptor"/>
           
           
              <!-- define the pointcut adviser -->
              <bean id="luceneInterceptor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
              	<property name="advice">
              		<ref local="luceneInterceptorAdvice"/>
              	</property>
              	<property name="pattern">
              		<value>.*save.*</value>
              	</property>
              </bean>
              <bean id="luceneInterceptorAdvice" class="com.vanitysoft.griffin.service.util.LuceneMethodInterceptor"/>
           
              <bean id="scheduler" class ="org.springframework.scheduling.quartz.SchedulerFactoryBean">   
          	<property name="dataSource"> 
          			<ref bean="dataSource"/> 
          	</property> 
          	<property name="applicationContextSchedulerContextKey"> 
          		<value>applicationContext</value> 
          	</property> 
          	<property name="jobListeners">
          		<ref bean="translationJobListener"/> 
          	</property>
          	</bean>
          	
          	 <bean id="translationJobListener" class ="com.vanitysoft.griffin.service.rss.job.TranslationJobListenerImpl">
          		  <property name="cacheProvider">
          			<ref bean="cacheProvider"/> 
          		 </property>
          		 <property name="channelDAO"><ref bean="channelDAO"/></property>
          		 <property name="rssExtensionDAO"><ref bean="rssExtensionDAO"/></property>
          	</bean>
                	 
             <bean id="ehcacheManager" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
          	<!--  <property name="configLocation"><value>ehcacheEhcacheTest.xml</value></property>-->
             </bean>   
          
          	<bean id="cacheProvider" class="org.springmodules.cache.provider.ehcache.EhCacheFacade">
          		<property name="cacheManager"> <ref bean="ehcacheManager"/></property>
          
          	    <!-- Same cache profiles specified as a java.util.Properties -->
          	    <property name="cacheProfiles">
          	        <props>
          	        	 <prop key="rssCache">&#91;cacheName=rssCache&#93;</prop>
          	        </props>
          	    </property>
          	</bean>	
           	
              <bean id="cacheInterceptorAdvice"  class="com.vanitysoft.griffin.service.util.CacheMethodInterceptor">    
              	<property name="cacheProvider">
              		<ref local="cacheProvider"/>
              	</property>
              </bean>
             
              <bean id="cacheInterceptor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
              	<property name="advice">
              		<ref local="cacheInterceptorAdvice"/>
              	</property>
              	<property name="pattern">
              		<value>.*get.*</value>
              	</property>
              </bean>
               
              	 
              <!-- Weave AOP into the interface for our delegate -->
              <bean id="griffinDelegate"  class="org.springframework.aop.framework.ProxyFactoryBean">
              	<property name="proxyInterfaces">
              		<value>com.vanitysoft.griffin.delegate.IGriffinDelegate</value>
              	</property>
              	<!-- define target of proxy-->
              	<property name="target">
              		<ref local ="griffinDelegateImpl"/>
              	</property>
              	<!-- wire in interceptor -->
              	<property name="interceptorNames">
              		<list>
             	  		    <value>exceptionInterceptorAdvice</value>    	  				 		
              		</list>
              	</property>
              </bean>    
               <bean id="griffinDelegateImpl"  class="com.vanitysoft.griffin.delegate.impl.GriffinDelegateImpl">
          		<property name="rssConverterService">
          			<ref local="rssService"/>
          		</property>
               </bean>   
           
           
               <bean id="translationService"  class="com.vanitysoft.griffin.service.lang.impl.TranslationServiceImpl">
           
               </bean>
              <bean id="iTuneRSSConverterService" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">	
          		<property name="transactionManager"><ref bean="transactionManager"/></property>
          		<property name="target"><ref local="iTuneRSSConverterServiceTarget"/></property>
          		<property name="transactionAttributes">
          			<props>
          				<prop key="*save">PROPAGATION_REQUIRED</prop> 
          			</props>
          		</property>
          	</bean>	
           
               <bean id="iTuneRSSConverterServiceTarget"  class="com.vanitysoft.griffin.service.itune.impl.ITuneRSSConverterServiceImpl">          
               	<property name="channelDAO">
          			<ref bean="channelDAO"/>
          		</property>
          	    <property name="rssExtensionDAO">
          			<ref bean="rssExtensionDAO"/>
          		</property>
               </bean>
              
           
             <bean id="rssService"  class="org.springframework.aop.framework.ProxyFactoryBean">
              	<property name="target">
              		<ref local ="rssServiceTarget"/>
              	</property>
                  <property name="proxyInterfaces">
                     <value>com.vanitysoft.griffin.service.rss.IRSSService</value>
                   </property>
                   <property name="interceptorNames">
                     <list>
                        <value>hibernateInterceptor</value>
                        <value>cacheInterceptor</value>
                     </list>
                   </property>	
              </bean>  
           
                <bean id="rssServiceTarget"  class="com.vanitysoft.griffin.service.rss.impl.RSSServiceImpl" >          
               	<property name="channelDAO">
          			<ref bean="channelDAO"/>
          		</property>
           	 <property name="rssExtensionDAO">
          			<ref bean="rssExtensionDAO"/>
          		</property>
          	 <property name="persistenceManager">
          			<ref bean="persistenceManagerHibernate"/>
          		</property>	
          	 <property name="cacheProvider">
          			<ref bean="cacheProvider"/>
          		</property>
          			 <property name="translationService">
          			<ref bean="translationService"/>
          		</property>
          	  <property name="scheduler">
          			<ref bean="scheduler"/>
          		</property>
          		<property name="poller"><ref bean="poller"/></property>
               </bean>
          </beans>

          the daoContext that it imports.

          Code:
          <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http&#58;//www.springframework.org/dtd/spring-beans.dtd">
          <beans>
               <!--Transaction for our business methods.-->
          	 <bean id="transactionManager" class="org.springframework.orm.hibernate.HibernateTransactionManager" singleton="true" lazy-init="default" autowire="default" dependency-check="default">
          	    	 <property name="sessionFactory"><ref bean="sessionFactory"/></property> 
          	 </bean>
          	 
          	<bean id="sessionFactory" class="org.springframework.orm.hibernate.LocalSessionFactoryBean" singleton="true" lazy-init="default" autowire="default" dependency-check="default">		 
             	     <property name="mappingDirectoryLocations">
              		<list>
          		      <value>classpath&#58;de/nava/informa/impl/hibernate</value>
          		      <value>classpath&#58;com/vanitysoft/griffin/domain/hibernate</value>		     
          		    </list>
            		</property>		 
          		 <property name="hibernateProperties">
          				<props> 
          					<prop key="hibernate.dialect">net.sf.hibernate.dialect.MySQLDialect</prop>
          					<prop key="hibernate.show_sql">true</prop>					
          					<prop key="hibernate.connection.provider_class">net.sf.hibernate.connection.C3P0ConnectionProvider</prop>
          				    <prop key="hibernate.connection.autoReconnect">true</prop >
          				    <prop key="hibernate.connection.autoReconnectForPools">true</prop >
          				    <prop key="hibernate.connection.is-connection-validation-required">true</prop >
          					<prop key="hibernate.cglib.use_reflection_optimizer">true</prop>
          					<prop key="hibernate.cache.use_query_cache">true</prop>
          					<!--<prop key="hibernate.hbm2ddl.auto">create</prop>-->
          				    <prop key="hibernate.cache.provider_class">net.sf.hibernate.cache.EhCacheProvider</prop> 				    
          				    <prop key="hibernate.c3p0.acquire_increment">3</prop >
          				    <prop key="hibernate.c3p0.idle_test_period">10</prop >
          					<prop key="hibernate.c3p0.timeout">30</prop>
          					<prop key="hibernate.c3p0.max_size">30</prop>
          					<prop key="hibernate.c3p0.max_statements">100</prop>				
          				    <prop key="hibernate.c3p0.min_size">1</prop> 
          				    <prop key="hibernate.c3p0.validate">true</prop> 			    
          				    <prop key="hibernate.connection.driver_class">org.gjt.mm.mysql.Driver</prop>
          					<prop key="hibernate.connection.url">jdbc&#58;mysql&#58;//localhost&#58;3306/griffin?</prop>
          					<prop key="hibernate.connection.username">root</prop>				
          				    <prop key="hibernate.connection.password">amwaym1</prop> 	    
          				</props>
          			</property> 
          	</bean>
           
           	 <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
          			<property name="driverClass"><value>org.gjt.mm.mysql.Driver</value></property>
            			<property name="jdbcUrl"><value>jdbc&#58;mysql&#58;//localhost&#58;3306/griffin?</value></property>
             			<property name="user"><value>root</value></property>
             			<property name="password"><value>amwaym1</value></property>
          	 </bean>
          	 
          	 <bean id="hibernateInterceptorAdvice" class="org.springframework.orm.hibernate.HibernateInterceptor">
                   <property name="sessionFactory">
                     <ref bean="sessionFactory"/>
                   </property>
              </bean>
              
               <bean id = "hibernateInterceptor" class = "org.springframework.aop.support.RegexpMethodPointcutAdvisor">
             	    <property name="advice">
              		<ref local="hibernateInterceptorAdvice"/>
              	</property>
              	<property name="pattern">
              		<value>.*get.*</value>
              	</property>	
              </bean>
          	 
          	 <bean id="rssExtensionDAO" class="com.vanitysoft.griffin.domain.hibernate.dao.impl.RssExtensionDAOImpl">
          		<property name="sessionFactory"><ref local="sessionFactory"/></property>
          	</bean>	
          	
             <bean id="pollerApprover" class="com.vanitysoft.griffin.service.informa.poller.impl.GriffinApproverImpl" singleton="true">
             </bean>
             
              <bean id="pollerObserver" class="com.vanitysoft.griffin.service.informa.poller.impl.GriffinPollerObserverImpl" singleton="true">
              <property name="persistenceManager"><ref local="persistenceManagerHibernate"/></property>
               	 <property name="rssExtensionDAO">
          			<ref bean="rssExtensionDAO"/>
          		</property>
             </bean>
              
              <bean id="persistencePollerObserver" class="de.nava.informa.utils.poller.PersistenceObserver" singleton="true" >	 
          		<constructor-arg>
          			 <ref local="persistenceManagerHibernate"/>
          		</constructor-arg>
          	</bean>	
          	
             <bean id="poller" class="com.vanitysoft.griffin.service.informa.poller.impl.GriffinPoller" singleton="true" >
          		<property name="period">
          			<value>36000</value>
          		</property>
          		<property name="workerThreads">
          			<value>10</value>
          		</property>
          			<property name="observers">
          			<list>
          				 <ref local="pollerObserver"/>
          				 <ref local="persistencePollerObserver"/>				 
          			 </list>
          		</property>
          	   <property name="approvers">
          			<list>
          				 <ref local="pollerApprover"/>		 
          			 </list>
          		</property>	
          	</bean>
          
               <bean id="persistenceManagerHibernate" class="de.nava.informa.utils.manager.hibernate.PersistenceManager" singleton="true" >
              </bean> 
          
           <!-- Wrapped in a transation -->
            <bean id="channelDAO" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">	
          		<property name="transactionManager"><ref bean="transactionManager"/></property>
          		<property name="target"><ref bean="channelDAOImpl"/></property>
          		<property name="transactionAttributes">
          			<props>
          				<prop key="*">PROPAGATION_REQUIRED</prop>
          			</props>
          		</property>
          	</bean>
          	 <bean id="channelDAOImpl" class="com.vanitysoft.griffin.domain.hibernate.dao.impl.ChannelDAOImpl">		
          	    <property name="persistenceManager"><ref local="persistenceManagerHibernate"/></property> 
          		<property name="sessionFactory"><ref local="sessionFactory"/></property>
          	    <property name="poller"><ref local="poller"/></property>
          	</bean>	
          	<!--  
          	 <bean id="categoryDAO"  class="org.springframework.aop.framework.ProxyFactoryBean">
              	<property name="target">
              		<ref local ="categoryDAOTarget"/>
              	</property>
                  <property name="proxyInterfaces">
                     <value>com.vanitysoft.griffin.domain.hibernate.dao.ICategoryDAO</value>
                   </property>
                   <property name="interceptorNames">
                     <list>
                        <value>hibernateInterceptor</value>
                     </list>
                   </property>	
              </bean> 
              -->
          	
           	 <bean id="categoryDAO" class="com.vanitysoft.griffin.domain.hibernate.dao.impl.CategoryDAOImpl">
          		<property name="sessionFactory"><ref local="sessionFactory"/></property>
          	</bean>	
           	
           </beans>

          Comment


          • #6
            Jerry,

            You're getting a complaint about there being 4 instances of the IRSSService interface. Now I'm not sure you're showing your entire code, as I only see 2 instances (unless I'm missing something), but even two instances is one two many for this use case.

            AbstractDependencyInjectionSpringContextTests and its subclasses by default inject by type, so if there is more than one bean of that type you're going to get the exception you got. There are a few different ways to work around this:

            1: if you just have two instances, and one is an outer proxy (like a transactional wrapper) and one is a target object, then as long as nobody needs the unwrapped target object (which is usually the case), then you can just make the target an inner bean of the wrapper, effectively hiding it from all byType autowiring. This is usually the easiest way to handle this problem when there is only one wrapper and one target.

            2: you can switch to by name autowiring of the test. In this case, you set the populateProtectedVariables property of the base test class to true, and it will autowire protected fields by _name_.

            3: you can manually get the problem bean yourself. Implement the onSetup() template method, and call
            Code:
            applicationContext.getBean&#40;"xxxx"&#41;
            to get the actual bean you need and set it as a field in your test case class.

            Regards,

            Comment


            • #7
              ?

              can you fix this to your solution u stated:
              1: if you just have two instances, and one is an outer proxy (like a transactional wrapper) and one is a target object, then as long as nobody needs the unwrapped target object (which is usually the case), then you can just make the target an inner bean of the wrapper, effectively hiding it from all byType autowiring. This is usually the easiest way to handle this problem when there is only one wrapper and one target.

              i don't understand what u mean...

              Code:
                <bean id="rssService"  class="org.springframework.aop.framework.ProxyFactoryBean"> 
                     <property name="target"> 
                        <ref local ="rssServiceTarget"/> 
                     </property> 
                      <property name="proxyInterfaces"> 
                         <value>com.vanitysoft.griffin.service.rss.IRSSService</value> 
                       </property> 
                       <property name="interceptorNames"> 
                         <list> 
                            <value>hibernateInterceptor</value> 
                            <value>cacheInterceptor</value> 
                         </list> 
                       </property>    
                  </bean>  
                
                    <bean id="rssServiceTarget"  class="com.vanitysoft.griffin.service.rss.impl.RSSServiceImpl" >          
                      <property name="channelDAO"> 
                       <ref bean="channelDAO"/> 
                    </property> 
                   <property name="rssExtensionDAO"> 
                       <ref bean="rssExtensionDAO"/> 
                    </property> 
                  <property name="persistenceManager"> 
                       <ref bean="persistenceManagerHibernate"/> 
                    </property>    
                  <property name="cacheProvider"> 
                       <ref bean="cacheProvider"/> 
                    </property> 
                        <property name="translationService"> 
                       <ref bean="translationService"/> 
                    </property> 
                   <property name="scheduler"> 
                       <ref bean="scheduler"/> 
                    </property> 
                    <property name="poller"><ref bean="poller"/></property> 
                   </bean>

              Comment


              • #8
                sovled thx.

                solved, thx to you both.


                Code:
                  <bean id="rssService"  class="org.springframework.aop.framework.ProxyFactoryBean"> 
                       <property name="target"> 
                          <bean class="com.vanitysoft.griffin.service.rss.impl.RSSServiceImpl" >          
                        <property name="channelDAO"> 
                         <ref bean="channelDAO"/> 
                      </property> 
                     <property name="rssExtensionDAO"> 
                         <ref bean="rssExtensionDAO"/> 
                      </property> 
                    <property name="persistenceManager"> 
                         <ref bean="persistenceManagerHibernate"/> 
                      </property>    
                    <property name="cacheProvider"> 
                         <ref bean="cacheProvider"/> 
                      </property> 
                          <property name="translationService"> 
                         <ref bean="translationService"/> 
                      </property> 
                     <property name="scheduler"> 
                         <ref bean="scheduler"/> 
                      </property> 
                      <property name="poller"><ref bean="poller"/></property> 
                     </bean> 
                       </property> 
                        <property name="proxyInterfaces"> 
                           <value>com.vanitysoft.griffin.service.rss.IRSSService</value> 
                         </property> 
                         <property name="interceptorNames"> 
                           <list> 
                              <value>hibernateInterceptor</value> 
                              <value>cacheInterceptor</value> 
                           </list> 
                         </property>    
                    </bean>

                Comment

                Working...
                X