Announcement Announcement Module
Collapse
No announcement yet.
@Repository component is not scanned -- please help Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • @Repository component is not scanned -- please help

    I have a GenericDaoJpa where I have basic CRUD methods. I am deploying this spring application on JBoss 5.1 . When the application server comes up I do not see the @Repository component being scanned and I think because of which the EntityManager is null.
    Can you please help? How can I tell if my @Repository component is scanned? also am I missing any config details?


    Here's my applicationContext.xml entry

    Code:
    	<jee:jndi-lookup id="entityManagerFactory" jndi-name="java:/ties-2EntityManagerFactory"/>
    	<context:component-scan base-package="com.rtd.ties2.dao" annotation-config="true">
    	</context:component-scan>
    GenericDaoJpa.java

    Code:
    package com.rtd.ties2.dao;
    
    import java.math.BigDecimal;
    import java.util.List;
    
    import javax.persistence.EntityManager;
    import javax.persistence.PersistenceContext;
    
    import org.apache.commons.logging.Log;
    import org.apache.commons.logging.LogFactory;
    import org.springframework.stereotype.Repository;
    
    import com.rtddenver.gwt.client.dto.entity.DomainObject;
    
    @Repository("genericDao")
    public class GenericDaoJpa<T extends DomainObject> implements GenericDao<T> {
    	
    	
    	private Class<T> type;
    	private static final Log log = LogFactory.getLog("GenericDaoJpa");
    	
    	@PersistenceContext(unitName="ties-2")
    	protected EntityManager entityManager;
    	public void setEntityManager(EntityManager entityManager){
    		this.entityManager = entityManager;
    	}
    	
    	public GenericDaoJpa(Class<T> type){
    		super();
    		this.type = type;
    	}
    
    	@Override
    	//@Transactional(readOnly=true)
    	public List<T> getAll() {
    		return entityManager.createQuery("select o from " + 
    				type.getName() + " o").getResultList();				
    	}
    
    	@Override
    	public void save(T object) {
    		entityManager.persist(object);		
    	}
    
    	@Override
    	public void delete(T object) {
    		entityManager.remove(object);
    	}
    
    	@Override
    	public T merge(T object) {
    		log.debug("merging instance");
    		try {
    			return entityManager.merge(object);
    		} catch (RuntimeException re) {
    			log.error("merge failed", re);
    			throw re;
    		}
    	}
    
    }
    jboss logs as the app is coming up

    Code:
    13:51:43,880 INFO  [STDOUT] 13:51:43,880 INFO  [XmlBeanDefinitionReader] Loading XML bean definitions from ServletContext resource [/WEB-INF/applicationContext.xml]
    13:51:44,020 INFO  [STDOUT] 13:51:44,020 INFO  [XmlBeanDefinitionReader] Loading XML bean definitions from ServletContext resource [/WEB-INF/spring-services.xml]
    13:51:44,036 INFO  [STDOUT] 13:51:44,036 INFO  [XmlBeanDefinitionReader] Loading XML bean definitions from ServletContext resource [/WEB-INF/ties2-servlet.xml]
    13:51:44,036 INFO  [STDOUT] 13:51:44,036 INFO  [DefaultListableBeanFactory] Overriding bean definition for bean 'messageSource': replacing [Generic bean: class [org.springframework.context.support.ReloadableResourceBundleMessageSource]; scope=singleton; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null; defined in ServletContext resource [/WEB-INF/applicationContext.xml]] with [Generic bean: class [org.springframework.context.support.ResourceBundleMessageSource]; scope=singleton; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null; defined in ServletContext resource [/WEB-INF/ties2-servlet.xml]]
    13:51:44,036 INFO  [STDOUT] 13:51:44,036 INFO  [XmlBeanDefinitionReader] Loading XML bean definitions from ServletContext resource [/WEB-INF/spring-security.xml]
    13:51:44,192 INFO  [STDOUT] 13:51:44,192 INFO  [XmlBeanDefinitionReader] Loading XML bean definitions from ServletContext resource [/WEB-INF/spring-master.xml]
    13:51:45,348 INFO  [STDOUT] 13:51:45,348 INFO  [XmlWebApplicationContext] Bean factory for application context [[email protected]1620e3c]: org.springframework.beans.factory.support.DefaultListableBeanFactory@13596bf
    13:51:45,738 INFO  [STDOUT] 13:51:45,738 INFO  [PropertyPlaceholderConfigurer] Loading properties file from class path resource [application.properties]
    13:51:45,926 INFO  [STDOUT] 13:51:45,926 INFO  [DefaultListableBeanFactory] Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@13596bf: defining beans [applicationProps,entityManagerFactory,org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,org.springframework.context.annotation.internalPersistenceAnnotationProcessor,dataSource,txMgr,messageSource,crystalConnect,contextApplicationContextProvider,userAdminService,userDataEntryFactory,routeService,dynamicParametersService,serviceTypeService,voteAdminService,crystalRptsUtils,selectableBizObj,runboardService,domainService,securityService,headwayService,reportService,divisionService,voteService,dynamicParametersDAO,routeDAO,divisionDAO,serviceTypeDAO,runboardDAO,etlDAO,userDAO,voteAdminDAO,headwayDAO,holidayDAO,reportDAO,org.springframework.web.servlet.mvc.support.ControllerBeanNameHandlerMapping#0,/login.do,/app/home.do,/app/gwt.do,/report.do,/app/uploadPrivateCarriers.do,tilesViewResolver,tilesConfigurer,multipartResolver,_authenticationManager,_filterChainProxy,_httpSessionContextIntegrationFilter,_filterChainProxyPostProcessor,_filterChainList,_securityContextHolderAwareRequestFilter,_accessManager,_portMapper,_exceptionTranslationFilter,_filterSecurityInterceptor,_sessionFixationProtectionFilter,_logoutFilter,_basicAuthenticationEntryPoint,_basicAuthenticationFilter,_entryPointInjectionBeanPostProcessor,_userServiceInjectionPostProcessor,authenticationProcessingFilter,authenticationProcessingFilterEntryPoint,tiesUserDetailsService,org.springframework.security.providers.dao.DaoAuthenticationProvider#0,org.springframework.security.config.AuthenticationProviderBeanDefinitionParser$AuthenticationProviderCacheResolver#0]; root of factory hierarchy
    13:51:45,972 INFO  [STDOUT] 13:51:45,972 INFO  [DriverManagerDataSource] Loaded JDBC driver: oracle.jdbc.driver.OracleDriver
    13:51:46,394 INFO  [STDOUT] 13:51:46,394 INFO  [ControllerBeanNameHandlerMapping] Mapped URL path [/login.do] onto handler [com.rtddenver.controller.LoginController@1e61035]
    13:51:46,394 INFO  [STDOUT] 13:51:46,394 INFO  [ControllerBeanNameHandlerMapping] Mapped URL path [/app/home.do] onto handler [com.rtddenver.controller.HomeController@1a0cce7]
    13:51:46,425 INFO  [STDOUT] 13:51:46,425 INFO  [ControllerBeanNameHandlerMapping] Mapped URL path [/app/gwt.do] onto handler [com.rtddenver.controller.GWTController@14ce60]
    13:51:46,425 INFO  [STDOUT] 13:51:46,425 INFO  [ControllerBeanNameHandlerMapping] Mapped URL path [/report.do] onto handler [com.rtddenver.controller.ReportController@19e2643]
    13:51:46,425 INFO  [STDOUT] 13:51:46,425 INFO  [ControllerBeanNameHandlerMapping] Mapped URL path [/app/uploadPrivateCarriers.do] onto handler [com.rtddenver.controller.runboards.FileUploadController@17921a7]
    13:51:46,488 INFO  [STDOUT] 13:51:46,488 INFO  [TilesConfigurer] TilesConfigurer: adding definitions [/WEB-INF/views.xml]
    13:51:46,503 INFO  [STDOUT] 13:51:46,503 INFO  [BasicTilesContainer] Initializing Tiles2 container. . .
    13:51:46,597 INFO  [STDOUT] 13:51:46,597 INFO  [BasicTilesContainer] Tiles2 container initialization complete.
    13:51:46,597 INFO  [STDOUT] 13:51:46,597 INFO  [TilesAccess] Publishing TilesContext for context: org.apache.catalina.core.ApplicationContextFacade
    13:51:46,722 INFO  [STDOUT] 13:51:46,722 INFO  [EntryPointInjectionBeanPostProcessor] Selecting AuthenticationEntryPoint for use in ExceptionTranslationFilter
    13:51:46,738 INFO  [STDOUT] 13:51:46,738 INFO  [EntryPointInjectionBeanPostProcessor] Using main configured AuthenticationEntryPoint.
    13:51:46,738 INFO  [STDOUT] 13:51:46,738 INFO  [EntryPointInjectionBeanPostProcessor] Using bean 'org.springframework.security.ui.webapp.AuthenticationProcessingFilterEntryPoint@1ee9293' as the entry point.
    13:51:46,769 INFO  [STDOUT] 13:51:46,769 INFO  [AbstractSecurityInterceptor] Validated configuration attributes
    13:51:46,862 INFO  [STDOUT] 13:51:46,862 INFO  [FilterChainProxyPostProcessor] Checking sorted filter chain: [org.springframework.security.context.HttpSessionContextIntegrationFilter[ order=200; ], org.springframework.security.ui.logout.LogoutFilter[ order=300; ], OrderedFilterDecorator[ delegate=com.rtddenver.security.TiesAuthenticationProcessingFilter[ order=700; ]; order=700], org.springframework.security.ui.basicauth.BasicProcessingFilter[ order=1000; ], org.springframework.security.wrapper.SecurityContextHolderAwareRequestFilter[ order=1100; ], org.springframework.security.ui.ExceptionTranslationFilter[ order=1400; ], org.springframework.security.ui.SessionFixationProtectionFilter[ order=1600; ], org.springframework.security.intercept.web.FilterSecurityInterceptor@10f1ff1]
    13:51:46,862 INFO  [STDOUT] 13:51:46,862 INFO  [FilterChainProxyPostProcessor] Filter chain...
    13:51:46,862 INFO  [STDOUT] 13:51:46,862 INFO  [FilterChainProxyPostProcessor] [0] - org.springframework.security.context.HttpSessionContextIntegrationFilter[ order=200; ]
    13:51:46,862 INFO  [STDOUT] 13:51:46,862 INFO  [FilterChainProxyPostProcessor] [1] - org.springframework.security.ui.logout.LogoutFilter[ order=300; ]
    13:51:46,862 INFO  [STDOUT] 13:51:46,862 INFO  [FilterChainProxyPostProcessor] [2] - com.rtddenver.security.TiesAuthenticationProcessingFilter[ order=700; ]
    13:51:46,862 INFO  [STDOUT] 13:51:46,862 INFO

  • #2
    Unfortunately, Generic DAOs don't mesh well with component scanning. This makes sense if you think about it - you need to be able to define multiple instances of this class, differing by the class passed into the constructor only. The class itself isn't capable of being autowired, so Spring can't do anything with it.

    For this part, your best bet is to just define the repo instances in XML. If you're really determined to use component-scanning, you'll have to subclass the Generic DAO and provide a default constructor that hardcodes the class i.e.

    Code:
    @Repository
    public class UserDao extends GenericDaoJPA<User> {
        public UserDao() {
            super(User.class);
        }
    }
    This isn't really worth the class bloat, so I'd suggest just configuring your DAO layer in XML.

    Hope this helps
    - Don

    Comment


    • #3
      Thanks Don for the response.

      I wrote a TiesVotesDaoJpa.java extending the GenericDaoJpa as you recommended. I still do not see the component @Repository scanned for the TiesVotesDaoJpa....I checked the logs of the jboss server as it was coming up but I do not see the string 'tiesVotesDao' in the log.
      Also, my entityManager object is still null.

      Does my configuration look right? and will I see the component name on the app server logs as it comes up?


      Code:
      package com.rtd.ties2.dao;
      
      import javax.persistence.EntityManager;
      import javax.persistence.PersistenceContext;
      
      import org.apache.commons.logging.Log;
      import org.apache.commons.logging.LogFactory;
      import org.springframework.stereotype.Repository;
      
      import com.rtd.ties2.session.TiesVotesHome;
      import com.rtddenver.gwt.client.dto.entity.modified.TiesVotes;
      
      @Repository("tiesVotesDao")
      public class TiesVotesDaoJpa extends GenericDaoJpa<TiesVotes> {
      	
      	private static final Log log = LogFactory.getLog(TiesVotesDaoJpa.class);
      	@PersistenceContext(unitName="ties-2")
      	protected EntityManager entityManager;
      	public void setEntityManager(EntityManager entityManager){
      		this.entityManager = entityManager;
      	}
      	public TiesVotesDaoJpa(Class<TiesVotes> type) {
      		super(type);
      	}
      }

      Comment


      • #4
        Not quite. Try this instead:

        Code:
        // imports skipped because I'm just that lazy
        
        @Repository("tiesVotesDao")
        public class TiesVotesDaoJpa extends GenericDaoJpa<TiesVotes> {
        	
                // ...
        	public TiesVotesDaoJpa() {
        		super(TiesVotes.class);
        	}
        }
        The key fact is that you can't pass in a non-autowired constructor param (the class name) and expect the component scanner to work.

        For reference, to do the same thing in XML, you could just say
        Code:
        <bean id="tiesVoteDao"
                 class="com.rtd.ties2.dao.GenericDao">
            <constructor-arg>com.rtddenver.gwt.client.dto.entity.modified.TiesVotes</constructor-arg>
        </bean>
        and remove the need for the subclass altogether. This is why I was saying that using XML for generic DAOs is generally preferable.

        Hope this helps
        - Don

        Comment


        • #5
          Don. Appreciate your responses...haven't solved the problem yet.
          Somehow think it could be related to my configuration.
          Should I not have the component-scan tag in applicationContext.xml?
          Some examples have them in a separate spring-master.xml

          Thank you for your help.

          applicationContext.xml

          Code:
          	<jee:jndi-lookup id="entityManagerFactory" jndi-name="java:/ties-2EntityManagerFactory">
          	</jee:jndi-lookup>
          		<context:component-scan base-package="com.rtd.ties2.dao" annotation-config="true">
          		<context:exclude-filter type="annotation"
          			expression="org.springframework.stereotype.Controller" />
          	</context:component-scan>
          modified my TiesVotesDaoJpa.java to look like what you have.

          Code:
          @Repository("tiesVotesDao")
          public class TiesVotesDaoJpa extends GenericDaoJpa<TiesVotes> {
          	
          	private static final Log log = LogFactory.getLog(TiesVotesDaoJpa.class);
          	@PersistenceContext
          	protected EntityManager entityManager;
          	public void setEntityManager(EntityManager entityManager){
          		this.entityManager = entityManager;
          	}
          	
          	public TiesVotesDaoJpa(){
          		super(TiesVotes.class);
          	}
          	public EntityManager getEntityManager(){
          		return entityManager;
          	}	
          }
          My calling service class looks like this.
          Code:
          package com.rtddenver.gwt.server;
          public class VoteServiceImpl implements VoteService  {
          
          	private TiesVotesDaoJpa votesDaoJpa = new TiesVotesDaoJpa();
          	@Override
          	public List<TiesVotes> getAllVoteNames() {
          		return votesDaoJpa.getAll();
          	}
          
          }
          GenericDaoJpa looks like this
          Code:
          public class GenericDaoJpa<T extends DomainObject> implements GenericDao<T> {
          	
          	
          	private Class<T> type;
          	private static final Log log = LogFactory.getLog("GenericDaoJpa");
          	
          	@PersistenceContext
          	protected EntityManager entityManager;
          	public void setEntityManager(EntityManager entityManager){
          		this.entityManager = entityManager;
          	}
          	
          	public GenericDaoJpa(Class<T> type){
          		super();
          		this.type = type;
          	}
          
          	@Override
          	//@Transactional(readOnly=true)
          	public T get(BigDecimal id) {
          		log.debug("getting instance with id: " + id);
          		if (id == null){
          			return null;
          		} 
          		else{
          			try {			
          				return entityManager.find(type, id);
          			} catch (RuntimeException re) {
          				log.error("get failed", re);
          				throw re;
          			}
          		}		
          	}
          
          	@Override
          	//@Transactional(readOnly=true)
          	public List<T> getAll() {
          		return entityManager.createQuery("select o from " + 
          				type.getName() + " o").getResultList();				
          	}

          Comment


          • #6
            Okay, you're much closer. At this point, your repository class is being scanned, but you're not actually using the scanned class.

            See, in your service class, you have the line

            Code:
             	private TiesVotesDaoJpa votesDaoJpa = new TiesVotesDaoJpa();
            This is returning an instance of the class managed by you, not Spring. To use the version that Spring's managing, you're typically going to want to have the service defined in Spring and inject the repository (using @Autowired or such).

            Based on the package name, it looks like this is a GWT project. I'm a little out of date on the most current techniques, but there are a number of ways out there to have the GWT client talk directly to a Spring-managed service. For this to work in the simplest fashion, you'll need to use one of those.

            Hope this helps
            - Don

            Comment


            • #7
              troubleshoot component scanning in spring

              Thanks Don.
              When I try to inject the votesJpa instance by @Autowired. I get the below exception. I still suspect my component is not being scanned. When JBoss comes up and reads my applicationContext.xml I see all other DAOs being initialized but not the one that has the @Repository annotation.
              I have no logs which tell me why it is not being scanned neither is it throwing any exceptions for the @Respository component.
              Please help, is there any way I can troubleshoot component scanning in spring?

              Here's my exception log when JBoss comes up

              Code:
              aused by: org.springframework.beans.factory.BeanCreationException: Could not autowire method: public void com.rtddenver.gwt.server.VoteServiceImpl.setTiesVotesDaoJpa(com.rtd.ties2.dao.TiesVotesDaoJpa); nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No unique bean of type [com.rtd.ties2.dao.TiesVotesDaoJpa] is defined: Unsatisfied dependency of type [class com.rtd.ties2.dao.TiesVotesDaoJpa]: expected at least 1 matching bean
              	at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredMethodElement.inject(AutowiredAnnotationBeanPostProcessor.java:578)
              	at org.springframework.beans.factory.annotation.InjectionMetadata.injectMethods(InjectionMetadata.java:117)
              	at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:270)
              	... 84 more
              Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No unique bean of type [com.rtd.ties2.dao.TiesVotesDaoJpa] is defined: Unsatisfied dependency of type [class com.rtd.ties2.dao.TiesVotesDaoJpa]: expected at least 1 matching bean
              my calling class

              Code:
              package com.rtddenver.gwt.server;
              
              
              
              import org.springframework.beans.factory.annotation.Autowired;
              
              import com.rtd.ties2.dao.TiesVotesDaoJpa;
              import com.rtddenver.gwt.client.dto.entity.modified.TiesVotes;
              import com.rtddenver.gwt.client.service.VoteService;
              
              public class VoteServiceImpl implements VoteService  {
              
              	private TiesVotesDaoJpa votesDaoJpa;
              	@Autowired
              	public void setTiesVotesDaoJpa(TiesVotesDaoJpa votesDaoJpa){
              		this.votesDaoJpa = votesDaoJpa;
              	}
              	@Override
              	public List<TiesVotes> getAllVoteNames() {
              		return votesDaoJpa.getAll();
              	}
              }

              Comment


              • #8
                resolved

                I have resolved this. Thanks Don for your pointers
                To see if your component is being scanned when JBoss AS comes up.
                Look for the below line in the server stacktrace.
                You can search for your @Repository component, in my case "tiesVotesDao"
                and it should be part of that line.


                Code:
                17:36:19,144 INFO  [STDOUT] 17:36:19,144 INFO  [PropertyPlaceholderConfigurer] Loading properties file from class path resource [application.properties]
                17:36:19,253 INFO  [STDOUT] 17:36:19,253 INFO  [DefaultListableBeanFactory] Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@1d2ed84: defining beans [applicationProps,entityManagerFactory,tiesVotesDao,org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,org.springframework.context.annotation.internalPersistenceAnnotationProcessor,dataSource,txMgr,messageSource,crystalConnect,contextApplicationContextProvider,userAdminService,userDataEntryFactory,routeService,dynamicParametersService,serviceTypeService,voteAdminService,crystalRptsUtils,selectableBizObj,runboardService,domainService,securityService,headwayService,reportService,divisionService,voteService,dynamicParametersDAO,routeDAO,divisionDAO,serviceTypeDAO,runboardDAO,etlDAO,userDAO,voteAdminDAO,headwayDAO,holidayDAO,reportDAO,org.springframework.web.servlet.mvc.support.ControllerBeanNameHandlerMapping#0,/login.do,/app/home.do,/app/gwt.do,/report.do,/app/uploadPrivateCarriers.do,tilesViewResolver,tilesConfigurer,multipartResolver,_authenticationManager,_filterChainProxy,_httpSessionContextIntegrationFilter,_filterChainProxyPostProcessor,_filterChainList,_securityContextHolderAwareRequestFilter,_accessManager,_portMapper,_exceptionTranslationFilter,_filterSecurityInterceptor,_sessionFixationProtectionFilter,_logoutFilter,_basicAuthenticationEntryPoint,_basicAuthenticationFilter,_entryPointInjectionBeanPostProcessor,_userServiceInjectionPostProcessor,authenticationProcessingFilter,authenticationProcessingFilterEntryPoint,tiesUserDetailsService,org.springframework.security.providers.dao.DaoAuthenticationProvider#0,org.springframework.security.config.AuthenticationProviderBeanDefinitionParser$AuthenticationProviderCacheResolver#0]; root of factory hierarchy

                Comment

                Working...
                X