Question

I'm trying to set up my first Java application using Spring Data for MongoDB in a multi-module Maven 3 project. Here are the relevant versions:

  • Java 7
  • mongodb-win32-x86_64-2.2.0
  • Spring Data 1.1.1.RELEASE
  • Spring 3.2.0.RELEASE

I'm getting the following runtime error:

Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'actorFacade': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private es.mi.casetools.praetor.persistence.springdata.repositories.ActorRepository es.mi.casetools.praetor.facade.impl.DefaultActorFacade.actorRepository; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'actorRepository': FactoryBean threw exception on object creation; nested exception is org.springframework.data.mapping.PropertyReferenceException: No property insert found for type void
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:287)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1106)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:517)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:294)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:225)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:291)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:609)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:932)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:479)
    at org.springframework.test.context.support.AbstractGenericContextLoader.loadContext(AbstractGenericContextLoader.java:106)
    at org.springframework.test.context.support.AbstractGenericContextLoader.loadContext(AbstractGenericContextLoader.java:57)
    at org.springframework.test.context.support.AbstractDelegatingSmartContextLoader.delegateLoading(AbstractDelegatingSmartContextLoader.java:100)
    at org.springframework.test.context.support.AbstractDelegatingSmartContextLoader.loadContext(AbstractDelegatingSmartContextLoader.java:248)
    at org.springframework.test.context.TestContext.loadApplicationContext(TestContext.java:124)
    at org.springframework.test.context.TestContext.getApplicationContext(TestContext.java:148)
    ... 30 more

Searching in google I found people with the same issue and it seems to be related with custom repositories.

Here is the entity I want to store as a mongo document.

public class Actor {
    public enum ActorStereotype {
        SYSTEM, 
        PERSON
    }
        private String id;
    private String code; // unique
    private ActorStereotype stereotype;
    private String title; // Short title for the actor
    private String description;
    private String projectId; // project this actor belongs to

        // getters & setters

The standard repository interface.

public interface ActorRepository extends MongoRepository<Actor, String>, ActorRepositoryCustom {
}

The custom interface (where I think the error lives).

@NoRepositoryBean
public interface ActorRepositoryCustom {
    void updateSingleActor(Actor actor);
    void insertActor(Actor actor);
}

The custom interface implementation.

public class ActorRepositoryCustomImpl implements ActorRepositoryCustom {
    @Autowired
    private MongoTemplate mongoTemplate;

    @Override
    public void updateSingleActor(Actor actor) {
        if(actor.getId() != null) 
            throw new MissingIdException();

        // TODO change to Spring Converter
        DBObject dbo = (DBObject)mongoTemplate.getConverter().convertToMongoType(actor);

        mongoTemplate.updateFirst(query(where("_id").is(actor.getId())), 
                Update.fromDBObject(dbo, new String[]{}), 
                Actor.class);
    }

    @Override
    public void insertActor(Actor actor) {  
        if(actor.getId() != null) 
            throw new IdProvidedException();

        mongoTemplate.save(actor);
    }

}

And finally, the application context.

    <context:annotation-config/>

    <bean id="propertyConfigurer"       class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="locations">
            <list>
                <value>classpath:properties/test.properties</value>
            </list>
        </property>
    </bean>

    <!-- mongodb configuration -->          
    <mongo:repositories base-package="es.mi.casetools.praetor.persistence.springdata.repositories" 
        mongo-template-ref="mongoTemplate" repository-impl-postfix="Impl">                  
        <repository:exclude-filter type="annotation" expression="org.springframework.data.repository.NoRepositoryBean"/>    
    </mongo:repositories>

    <mongo:mongo id="mongotest" host="${mongo.host}" port="${mongo.port}" write-concern="SAFE">
    </mongo:mongo>

    <mongo:db-factory dbname="${mongo.dbname}" mongo-ref="mongotest"/>

    <bean id="mongoTemplate" class="org.springframework.data.mongodb.core.MongoTemplate">
        <constructor-arg name="mongoDbFactory" ref="mongoDbFactory"/>
    </bean> 
    <bean id="actorFacade" class="es.mi.casetools.praetor.facade.impl.DefaultActorFacade">
    </bean>

</beans>

I also have a little Spring test that fails loading the above application context giving the exception I listed near the top.

I tried adding the following but I get the same exception.

<bean id="actorRepositoryCustomImpl" class="es.mi.casetools.praetor.persistence.springdata.repositories.ActorRepositoryCustomImpl"></bean>

Has someone got a clue of what the error may be?

Was it helpful?

Solution

Miguel's comment solved the problem. I had given the wrong name to the implementing class. I've seen similar questions around so I'll try to clarify the solution in the hope that it helps someone else.

I have the following interface definition

public interface ActorRepository extends MongoRepository<Actor, String>, ActorRepositoryCustom

The custom interface definition looks like this:

public interface ActorRepositoryCustom

So my error was naming the implementation of ActorRepositoryCustom with ActorRepositoryCustomImpl, expecting Springdata would pick up the implementation as its postfix is the default one Impl. The thing is, Springdata looks for ActorRepositoryImpl by default, even though what you are implementing is ActorRepositoryCustom. The solution is using the optional attribute repository-impl-postfix and set it to CustomImpl.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top