1

I've recently started learning Java, as well as Spring 5 and Spring Boot. I'm relatively new to creating web-services, so to start off I'm creating an online pet store API. I've been following source code from this here github tutorial as a guide: https://github.com/in28minutes/spring-boot-examples/tree/master/spring-boot-2-rest-service-with-swagger

To deploy the API, I run the following commands:

~mvn clean install
~mvn spring-boot:run

It builds successfully, no errors or warnings. However, when I use the spring-boot:run command, I get the following message:

Failed to execute goal org.springframework.boot:spring-boot-maven-plugin:2.0.2.RELEASE:run (default-cli) on project gs-rest-service: An exception occurred while running. null: InvocationTargetException: Error creating bean with name 'petController': Unsatisfied dependency expressed through field 'petRepository'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'petstore.pet.PetRepository' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)} -> [Help 1]

I've googled everywhere but I can't seem to find an answer. My code is as follows:

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.springframework</groupId>
    <artifactId>gs-rest-service</artifactId>
    <version>0.1.0</version>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.2.RELEASE</version>
    </parent>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>com.jayway.jsonpath</groupId>
            <artifactId>json-path</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.hibernate.javax.persistence</groupId>
            <artifactId>hibernate-jpa-2.1-api</artifactId>
            <version>1.0.0.Final</version>
        </dependency>
        <dependency>
            <groupId>org.hibernate.javax.persistence</groupId>
            <artifactId>hibernate-jpa-2.0-api</artifactId>
            <version>1.0.1.Final</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.data</groupId>
            <artifactId>spring-data-jpa</artifactId>
            <version>2.0.7.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-beans</artifactId>
            <version>5.0.6.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>javax.inject</groupId>
            <artifactId>javax.inject</artifactId>
            <version>1</version>
        </dependency>
    </dependencies>

    <properties>
        <java.version>1.8</java.version>
    </properties>


    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

    <repositories>
        <repository>
            <id>spring-releases</id>
            <url>https://repo.spring.io/libs-release</url>
        </repository>
    </repositories>
    <pluginRepositories>
        <pluginRepository>
            <id>spring-releases</id>
            <url>https://repo.spring.io/libs-release</url>
        </pluginRepository>
    </pluginRepositories>
</project>

src/main/java/petstore/PetStoreApplication.java

package petstore;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class PetStoreApplication
{
    public static void main(String[] args)
    {
        SpringApplication.run(PetStoreApplication.class, args);
    }
}

src/main/java/petstore/pet/Pet.java

package petstore.pet;

import com.sun.javafx.beans.IDProperty;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;

@Entity
public class Pet {

    @Id
    @GeneratedValue
    private long id;

    private String name;
    private String status;

    public Pet(long id, String name, String status)
    {
        this.id = id;
        this.name = name;
        this.status = status;
    }

    public long getId()
    {
        return this.id;
    }

    public String getName()
    {
        return this.name;
    }

    public String getStatus()
    {
        return this.status;
    }

    public void setId(long id)
    {
        this.id = id;
    }

    public void setName(String name)
    {
        this.name = name;
    }

    public void setStatus(String status)
    {
        this.status = status;
    }
}

src/main/java/petstore/pet/PetRepository.java

package petstore.pet;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface PetRepository extends JpaRepository<Pet, Long>
{

}

src/main/java/petstore/PetController.java

package petstore.pet;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;


@RestController
public class PetController
{
    @Autowired
    private PetRepository petRepository;

    @GetMapping("/pets")
    public List<Pet>retrieveAllPets()
    {
        return petRepository.findAll();
    }
}

src/main/java/petstore/pet/PetNotFoundException.java

package petstore.pet;

public class PetNotFoundException extends RuntimeException
{
    public PetNotFoundException(String exception)
    {
        super(exception);
    }
}

I believe I'm missing something with the wiring, but I'm unsure how to resolve it, and googling didn't get me very far either. Apologies for the lengthy question. Any help is much appreciated.

fluffyBatman
  • 6,524
  • 3
  • 24
  • 25
NodziGames
  • 395
  • 3
  • 17
  • You shouldn’t have all classes in same package. – Lemmy Jun 19 '18 at 05:54
  • I see your pom has conflicting jpa jar dependency. ` org.hibernate.javax.persistence hibernate-jpa-2.1-api 1.0.0.Final org.hibernate.javax.persistence hibernate-jpa-2.0-api 1.0.1.Final ` – Amith Kumar Jun 19 '18 at 05:54
  • 2
    Remove the `spring-beans`, `spring-data-jpa` and `hibernate` dependencies and add a single `spring-boot-starter-data-jpa` dependency which will make sure you have the proper dependencies. You might also want to remove `javax.inject` as well as you aren't currently using those annotations. The main problem is you are missing a jpa provider, in this case Hibernate. The `spring-boot-starter-data-jpa` takes care of all those dependencies for you . – M. Deinum Jun 19 '18 at 05:56

3 Answers3

0

You have to add @EnableJpaRepositories(basePackages = ...) in Spring configuration because Spring doesn't know which packages search to find your PetRepository

Rafał Sokalski
  • 1,817
  • 2
  • 17
  • 29
  • `@SpringBootApplication` takes care of the `ComponentScan` and thus with `@Repository` annotation, spring context can detect it. – Amith Kumar Jun 19 '18 at 05:56
  • Do you see ComponentScan here ? – Rafał Sokalski Jun 19 '18 at 05:57
  • By default, Spring Boot will enable JPA repository support and look in the package (and its subpackages) where @SpringBootApplication is located, so if the repository is in different package it would't be visible – Rafał Sokalski Jun 19 '18 at 05:58
  • `The @SpringBootApplication annotation is equivalent to using @Configuration, @EnableAutoConfiguration, and @ComponentScan with their default attributes`. [Link](https://docs.spring.io/spring-boot/docs/current/reference/html/using-boot-using-springbootapplication-annotation.html) – Amith Kumar Jun 19 '18 at 05:59
  • @RafałSokalski in the above example, repository is in the same package. – Pramod Jun 19 '18 at 06:00
0

Could try adding the below dependency.

 <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-jpa</artifactId>
  </dependency>

Also version is not needed as Spring boot has this auto configuration property where it will automatically pick up the feasible version of each dependency.

If we manage our dependencies “manually”, we need specify the version numbers of all dependencies.

0

You should include only the following dependencies to make your application work. Also, I have added h2 database dependency as you might need one for your application to work. Feel free to change it accordingly for your used database.

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
     <dependency>
        <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
    </dependency>           
    <dependency>
        <groupId>org.springframework.data</groupId>
        <artifactId>spring-data-jpa</artifactId>
    </dependency>
    <dependency>
        <groupId>com.h2database</groupId>
        <artifactId>h2</artifactId>
    </dependency>
</dependencies>
skelwa
  • 575
  • 1
  • 7
  • 17
  • Thank you for the answer. Turns out IntelliJ added a different Jpa handler under the javax.persistance framework instead of the spring-boot-starter-data-jpa one. Also, it seems that the h2 database was indeed required. – NodziGames Jun 20 '18 at 06:10