Announcement Announcement Module
Collapse
No announcement yet.
MongoEventListener: unresolvable circular reference when referencing mongoTemplate Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • MongoEventListener: unresolvable circular reference when referencing mongoTemplate

    I am trying to use the Mongo Lifecycle Event support provided by Spring Data ( http://static.springsource.org/sprin...g-usage.events ) and am having problems when I attempt to have my event listener be injected with a reference to either a mongoTemplate or a repository object; it throws BeanCreationExceptions.

    As an example, here is part of one of my listeners. It is supposed to auto-populate a field before saving the visitor object by looking up some data.

    The only way I've gotten this to work was to not use bean injection on my EventListener. Instead I had it be ApplicationContextAware, and looked up the objects from the context right before I called them. This kind of defeats the purpose of using DI, so I'm not happy with it. Any suggestions?
    Code:
    public class VisitorMongoEventListener extends AbstractMongoEventListener<Visitor> {
    	@Autowired
    	private MongoTemplate mongoTemplate; // This line causes it to fail
    
    	@Autowired
    	private VisitorRepository visitorRepository; // This line also causes it to fail
    
    	@Override
    	public void onBeforeConvert(Visitor source) {
    		if (StringUtils.isBlank(source.setEmbeddedValue())) {
    			String value= visitorRepository.lookupSomeOtherValueToEmbed(source);
    			source.setEmbeddedValue(value);
    		}
    	}
    and it throws the following exception stack.
    Code:
    ERROR [2011-09-28 16:37:26,944] [Thread-1] (ContextLoader.java:227) - Context initialization failed
    org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'mongoTemplate' defined in class path resource [application-mongo.xml]: Cannot resolve reference to bean 'mappingConverter' while setting constructor argument; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'mappingConverter': Cannot resolve reference to bean 'mappingContext' while setting constructor argument; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'mappingContext': Invocation of init method failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'com.han.mongo.listeners.VisitorMongoEventListener#0': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private org.springframework.data.mongodb.core.MongoTemplate com.han.mongo.listeners.VisitorMongoEventListener.mongoTemplate; nested exception is org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'mongoTemplate': Requested bean is currently in creation: Is there an unresolvable circular reference?
    	at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:328)
    <snip>
    Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'mappingConverter': Cannot resolve reference to bean 'mappingContext' while setting constructor argument; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'mappingContext': Invocation of init method failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'com.han.mongo.listeners.VisitorMongoEventListener#0': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private org.springframework.data.mongodb.core.MongoTemplate com.han.mongo.listeners.VisitorMongoEventListener.mongoTemplate; nested exception is org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'mongoTemplate': Requested bean is currently in creation: Is there an unresolvable circular reference?
    	at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:328)
    <snip>
    Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'mappingContext': Invocation of init method failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'com.han.mongo.listeners.VisitorMongoEventListener#0': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private org.springframework.data.mongodb.core.MongoTemplate com.han.mongo.listeners.VisitorMongoEventListener.mongoTemplate; nested exception is org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'mongoTemplate': Requested bean is currently in creation: Is there an unresolvable circular reference?
    	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1420)
    <snip>
    Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'com.han.mongo.listeners.VisitorMongoEventListener#0': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private org.springframework.data.mongodb.core.MongoTemplate com.han.mongo.listeners.VisitorMongoEventListener.mongoTemplate; nested exception is org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'mongoTemplate': Requested bean is currently in creation: Is there an unresolvable circular reference?
    	at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:288)
    <snip>
    Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private org.springframework.data.mongodb.core.MongoTemplate com.han.mongo.listeners.VisitorMongoEventListener.mongoTemplate; nested exception is org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'mongoTemplate': Requested bean is currently in creation: Is there an unresolvable circular reference?
    	at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:508)
    <snip>
    Caused by: org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'mongoTemplate': Requested bean is currently in creation: Is there an unresolvable circular reference?
    	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.beforeSingletonCreation(DefaultSingletonBeanRegistry.java:297)
    <snip>

  • #2
    That's a coincidence. I encountered the same problem two days ago. I also had to use the ApplicationContextAware workaround.
    I try to inject MongoTemplate into an ApplicationListener class.

    Code:
    public class SessionDestroyedListener implements ApplicationListener<SessionDestroyedEvent> {
    	@Autowired
    	private MongoTemplate mongoTemplate;
    }
    This will cause a "Error creating bean with name 'mongoTemplate': Requested bean is currently in creation: Is there an unresolvable circular reference?" error.



    The weird part is that there is also an ApplicationListener on ContextRefreshEvent and here the autowiring of MongoTemplate works.

    Code:
    @Component
    public class Startup implements ApplicationListener<ContextRefreshedEvent> {
    
    	@Autowired
    	private MongoTemplate mongoTemplate;
    }
    I have no idea why one works and the other throws an exception. I hope somebody can shed some light on this issue.
    Last edited by rasch; Sep 29th, 2011, 01:28 AM. Reason: added code tags

    Comment


    • #3
      Hi,
      Appreciate if you could share your implementation of ApplicationContextAware. I am having similar problem.
      many thanks
      canal

      Comment


      • #4
        This is from memory, so I don't guarantee that it's correct but it'd be a starting point...

        Code:
        public class VisitorMongoEventListener extends AbstractMongoEventListener<Visitor> implements ApplicationContextAware {
        	private ApplicationContext applicationContext;
        	private String repositoryName;
        	private VisitorRepository visitorRepository = null;
        
        
        	public void setApplicationContext(ApplicationContext applicationContext) {
        		this.applicationContext = applicationContext;
        	}
        
        	public void setRepositoryName(String name) {
        		this.repositoryName = name;
        	}
        
        	public VisitorRepository getVisitorRepository() {
        		if (visitorRepository == null) {
        			visitorRepository = (VisitorRepository)(applicationContext.getBean(repositoryName));
        		}
        		return visitorRepository;
        	}
        
        @Override
        	public void onBeforeConvert(Visitor source) {
        		if (StringUtils.isBlank(source.setEmbeddedValue())) {
        			String value= getVisitorRepository().lookupSomeOtherValueToEmbed(source);
        			source.setEmbeddedValue(value);
        		}
        	}
        }

        Comment


        • #5
          thank you very much!

          Comment


          • #6
            Injection into fields is considered bad practice anyway (how would you unit test that class?). Setter injection should work. The general problem is that you introduce a circular dependency Listener > MongoTemplate > MappingContext > Listener. Would it make sense to implement a custom Converter for your Visitor class instead?

            Comment

            Working...
            X