-1

I'm trying to follow a book title Spring MVC beginner's guide and I'm stuck at creating repository object. I keep on getting a BeanCreationException. Not sure what else I missed. I'm wondering if somebody can help me to figure out this issue.

Please find below my code. Thanks.

BeanCreationException

org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.packt.webstore.domain.repository.ProductRepository] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}

XML FILE:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans 
http://www.springframework.org/schema/beans/spring-beans.xsd 
http://www.springframework.org/schema/context 
http://www.springframework.org/schema/context/spring-context-4.0.xsd 
http://www.springframework.org/schema/mvc 
http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd">

<mvc:annotation-driven/>
<context:component-scan base-package="com.packt.webstore"/>


<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views/"/>
<property name="suffix" value=".jsp"/>
</bean>
</beans>

ProductCrontroller:

package com.packt.webstore.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import com.packt.webstore.domain.repository.ProductRepository;
import org.springframework.beans.factory.annotation.Autowired;

@Controller
public class ProductController  {

    @Autowired
    private ProductRepository productRepository;


    @RequestMapping("/products")
    public String list(Model model){        
        model.addAttribute("products",productRepository.getAllProducts());

        return "products";
    }
}

ProductRepository:

package com.packt.webstore.domain.repository;
import java.util.List;
import com.packt.webstore.domain.Product;

public interface ProductRepository {

    List<Product>getAllProducts();  

}

InMemoryProductRepository:

package com.pckt.webstore.domain.repository.impl;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import org.springframework.stereotype.Repository;
import com.packt.webstore.domain.Product;
import com.packt.webstore.domain.repository.ProductRepository;

@Repository
public class InMemoryProductRepository implements ProductRepository{

    private List<Product> listOfProducts=new ArrayList<Product>();

    public InMemoryProductRepository(){
        Product iphone=new Product("P1234","iPhone 6", new BigDecimal(500));

        iphone.setDescription("Apple iphone 6 smartphone with 4 inch 640 x 1136 display and 8-megapixel rear camera");
        iphone.setCategory("Smart Phone");
        iphone.setManufacturer("Apple");
        iphone.setunitInStock(1000);

        Product laptop_dell=new Product("P1235","Dell Inspiron", new BigDecimal(700));

        laptop_dell.setDescription("Dell Inspiron 14-inch Laptop (Black) with 3rd Generation Intel Core processors");
        laptop_dell.setCategory("Laptop");
        laptop_dell.setManufacturer("Dell");
        laptop_dell.setunitInStock(1000);

        Product tablet_Nexus=new Product("P1236","Nexus 7", new BigDecimal(300));

        tablet_Nexus.setDescription("Google Nexus 7 is the lightest 7 inch tablet with a QualComm Snapdragon S4 Pro Processor");
        tablet_Nexus.setCategory("Tablet");
        tablet_Nexus.setManufacturer("Google");
        tablet_Nexus.setunitInStock(1000);

        listOfProducts.add(iphone);
        listOfProducts.add(laptop_dell);
        listOfProducts.add(tablet_Nexus);
    }

    public List<Product>getAllProducts(){
        return listOfProducts;
    }
}     
kingAm
  • 1,755
  • 1
  • 13
  • 23
Oaen
  • 35
  • 2
  • 9

4 Answers4

0

It seems you are using Spring 4, but not using Spring Boot, probably you are new to Spring, so take my advice and instead of using "pure" Spring, use Spring Boot, which is an awesome project which ease a lot working with Spring. With Spring Boot you will get a lot of configuration for free, you will get easy dependency management for many Spring libraries and thirdy party components, you won't need to use XML for configuration, and a lot more. Currently is the recommended way to start a Spring project.

That was the first part of my answer. The second part, you are getting that exception prolly because of the type @Reimeus mention. As your repository annotation is not in the com.packt.webstore you marked as the base package for component scan, then the Spring container cannot find a Repository annotation.

Mario
  • 227
  • 1
  • 2
  • 7
  • Thanks. Reimeus, that explains it. It works now thank you very much. :D Hi Mario yes I'm very new to Spring, I just picked up the book yesterday and I'm really interested to learn it. I am used to using Grails, and so I thought there should be an easier to configure this. If I start with Spring boot as a newbie would it fast track my learning curve? or should I start with the spring 4 as fundamental spring? – Oaen Jun 14 '15 at 01:45
  • Definitely Spring Boot is the way to go. It incredibely ease the learning process and in the end you are using Spring, is just some "sort of layer" on top of it to ease configuration, dependency management, development process, and many more things. You can find how to use it here: spring.io/guides There is a lot of info about Spring Boot and Spring in general – Mario Jun 14 '15 at 13:14
  • Thanks i'll surely look at it. Do you know of books to read for JPA, Hibernate and Databases, MySQL? Thanks – Oaen Jun 14 '15 at 15:25
  • **Pro JPA 2, 2nd Edition** That one is awesome – Mario Jun 15 '15 at 16:41
0

I think you need to add the @Component annotation on that class. This way, Spring can scan that file and register it as a bean in the context.

Makoto
  • 104,088
  • 27
  • 192
  • 230
Smiles
  • 46
  • 8
0

In your XML file, you have this.

<context:component-scan base-package="com.packt.webstore"/>

This means that Spring looks for Beans in that package, by looking at classes annotated with @Component, @Repository, @Service, @Controller, or any other annotation that marks the class as a bean.

The bean you want to get is of type ProductRepository. Now, the ProductRepository interface is on a different package than its Implementation

com.packt.webstore.domain.repository

vs

com.packt.webstore.domain.repository.impl

Since the class with @Repository is in the latter, you should have another component scan

<context:component-scan base-package="com.packt.webstore.domain.repository.impl"/>

This tells Spring that there are classes in that package that should be treated as beans.

Last note, I do suggest putting the Implementation and Interface in exactly the same package.

Richard Drew
  • 86
  • 1
  • 7
0

You can specify qualification for your Beans, so that Spring will not be confused about which Bean to auto wire.

In InMemoryProductRepository.java:

@Repository("InMemoryProductRepository")
public class InMemoryProductRepository implements ProductRepository {
    ...
}

In ProductController.java:

@Controller
public class ProductController {
    @Autowired
    @Qualifier("InMemoryProductRepository")
    private ProductRepository productRepository;
    ...
}
coderz
  • 4,847
  • 11
  • 47
  • 70