Results 1 to 8 of 8

Thread: @Repository component is not scanned -- please help

  1. #1
    Join Date
    May 2009
    Location
    Denver, CO
    Posts
    17

    Default @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 [org.springframework.web.context.support.XmlWebApplicationContext@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. #2
    Join Date
    Nov 2005
    Posts
    113

    Default

    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

  3. #3
    Join Date
    May 2009
    Location
    Denver, CO
    Posts
    17

    Default

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

  4. #4
    Join Date
    Nov 2005
    Posts
    113

    Default

    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

  5. #5
    Join Date
    May 2009
    Location
    Denver, CO
    Posts
    17

    Default

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

  6. #6
    Join Date
    Nov 2005
    Posts
    113

    Default

    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

  7. #7
    Join Date
    May 2009
    Location
    Denver, CO
    Posts
    17

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

  8. #8
    Join Date
    May 2009
    Location
    Denver, CO
    Posts
    17

    Default 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

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •