简体   繁体   中英

Error with spring bean configuraion while trying to autowire class that usind Morphia with MongoDB

I have a controller that is using a facade that using DAO in order to save some values into the DB here is the stracture:

Controller:

@Controller
@RequestMapping("stores/Items")
@ContextConfiguration("classpath:application-context-core-production.xml")
public class ItemsController {

    @Autowired
    IItemsFacade itemsFacade;   
}

Facade:

@Service
public class ItemsFacade implements IItemsFacade {

    @Autowired
    ItemDAO itemDAO;
}

DAO:

@Repository
public class ItemDAO extends BasicDAO<Item, ObjectId> implements IItemDAO{


    @Autowired
    public ItemDAO(MongoClient mongoClient, Morphia morphia, String mongoDB) {
        super(mongoClient, morphia, mongoDB);
    }
}

application-context-core-production.xml:

<context:component-scan base-package="com.salegroup.*" />
<!-- Setup Mongo and Morphia -->
<mongo:mongo host="localhost" port="27017" />

<bean class="java.lang.String" id="mongoDB">
    <constructor-arg value="sale" />
</bean>

<bean class="com.mongodb.MongoClient" id="mongo" />
<bean class="org.mongodb.morphia.Morphia" id="morphia" />


<bean class="com.salegroup.persistence.dao.item.impl.ItemDAO" id="itemDAO">
    <constructor-arg ref="mongo" index="0" />
    <constructor-arg ref="morphia" index="1" />
    <constructor-arg ref="mongoDB" index="2" />
</bean>

The DAO should connect into the mongoDB, I'm using the xml configuration inorder to create the MongoClient and Morfia.

while trying to run in in embeded tomcat server i'm getting the following error:

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'itemDAO' defined in file 
[...\ItemDAO.class]: Unsatisfied dependency expressed through constructor argument with index 1 of type [org.mongodb.morphia.Morphia]: : No qualifying bean of type [org.mongodb.morphia.Morphia] 
found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. 
Dependency annotations: {}; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [org.mongodb.morphia.Morphia] found for dependency:
 expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}

    at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:749) ~[spring-beans-4.2.4.RELEASE.jar:4.2.4.RELEASE]
    at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:185) ~[spring-beans-4.2.4.RELEASE.jar:4.2.4.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1143) ~[spring-beans-4.2.4.RELEASE.jar:4.2.4.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1046) ~[spring-beans-4.2.4.RELEASE.jar:4.2.4.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:510) ~[spring-beans-4.2.4.RELEASE.jar:4.2.4.RELEASE]

What did i miss? must say in case i'm removing in from the facade class everything is working (...dahhh..).

In addition to that tests are working as well and i'm getting a valid conneciton into the DB.

Any idea?

there are two problems in your code

  1. the annotation @ContextConfiguration is not dedicated for importing xml configuration files except in the case of integratointesting

@ContextConfiguration defines class-level metadata that is used to determine how to load and configure an ApplicationContext for integration tests. API

  1. The xml configuration file never gets parsed that is why Morphia instance is not found to be autowired and even if this happens and your xml configuration file gets parsed you will get 2 instances of ItemDAO in your container wich probably you don't want

if you are using Annptation based configuration for spring here is what you are going to do

First Approach

  • in your Configuration class(the one annotated with @Configuration) you annotate it like this

     @Configuration @ImportResource("classpath:application-context-core-production.xml") public class AppConfig{...} 
  • you remove the annotation @Repository and @Autowired from the class ItemDAO

Second Aproach

forget totally about xml config and do it all in annotations like this

@Configuration 
@PropertySource("classpath:mongo.properties")
public class AppConfig{
   // some methods ...
   @Bean
   public Mongo mongo(@Value("${mongo.host.addr}")String host,@Value("${mongo.host.port}")int port){
       return new Mongo(host,port);
   }
   @Bean
   public Morphia morphia(){
      return new Morphia();
   } 
}

in your repository class

    @Repository
public class ItemDAO extends BasicDAO<Item, ObjectId> implements IItemDAO{


    @Autowired
    public ItemDAO(MongoClient mongoClient, Morphia morphia,@Value("${mongo.mongoDB}") String mongoDB) {
        super(mongoClient, morphia, mongoDB);
    }
}

in your classpath mongo.properties

mongo.DB=sale
mongo.host.addr=localhost
mongo.host.port=27017

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM