1
votes

Comment réparer: erreur lors de la création du bean avec le nom: dépendance non satisfaite exprimée par le champ

J'essaye de mettre en place une API de repos de ressort en utilisant la mise en veille prolongée. Lorsque j'essaye d'utiliser le userRespository que j'ai configuré, j'obtiens cette erreur

src
-main
--java
---com.potholeapi
----controllers
----models
----repositories
----services
-----impl
-resources
pom.xml

Voici le modèle, le contrôleur et les fichiers d'application

Modèle

spring.datasource.url = jdbc:mysql://localhost:3306/PotholeDB?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC
spring.datasource.username = admin
spring.datasource.password = admin

spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MariaDB53Dialect

spring.jpa.hibernate.ddl-auto = update

Manette

<?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 https://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>
    <name>potholeAPI</name>

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

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>com.jayway.jsonpath</groupId>
            <artifactId>json-path</artifactId>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.15</version>
            <scope>provided</scope>
        </dependency>

        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>3.8.1</version>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>com.h2database</groupId>
            <artifactId>h2</artifactId>
            <scope>runtime</scope>
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-data-jpa -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
            <version>2.1.8.RELEASE</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>

</project>

Dépôt

package com.potholeapi;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.transaction.annotation.EnableTransactionManagement;

@Configuration
@EntityScan
@EnableJpaRepositories(basePackages = "com.potholeapi.repositories")
@EnableTransactionManagement
@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

Un service

package com.potholeapi.services.impl;

import com.potholeapi.models.User;
import com.potholeapi.repositories.UserRepository;
import com.potholeapi.services.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

@Service
public class UserServiceImpl implements UserService {
    @Autowired
    private UserRepository userRepository;

    @Override
    public List<User> getUsers(){
        List<User> out = new ArrayList<User>();
        userRepository.findAll().forEach(user -> out.add(user));
        return out;
    }
}

ServiceImpl

package com.potholeapi.services;

import com.potholeapi.models.User;

import java.util.List;
import java.util.Optional;

public interface UserService {
    List<User> getUsers();
}

Application

package com.potholeapi.repositories;

import com.potholeapi.models.User;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface UserRepository extends JpaRepository<User, Long> {}

pom.xml

package com.potholeapi.controllers;

import com.potholeapi.repositories.UserRepository;
import com.potholeapi.services.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import com.potholeapi.models.User;

import java.util.ArrayList;
import java.util.List;

@RestController
public class UserController {
    @Autowired
    private UserService userService;

    /**
     * Get all users list.
     *
     * @return the list
     */
    @GetMapping("/users")
    public List<User> getAllUsers() {
        return  userService.getUsers();
    }
}

application.properties

package com.potholeapi.models;

import org.hibernate.annotations.Entity;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;

import java.io.Serializable;
import javax.persistence.*;

@Entity
@Table(name = "User")
public class User implements Serializable{

    private static final long serialVersionUID = 1L;

    @Id
    @Column(name = "id", unique = true)
    private Long id;

    @Column(name = "name", unique = true)
    private String name;

    @Column(name = "created_date")
    private int created_date;

    public Long getId() {
        return id;
    }

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

    public String getName() {
        return name;
    }

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

    public int getCreated_date() {
        return created_date;
    }

    public void setCreated_date(int created_date) {
        this.created_date = created_date;
    }
}

structure de répertoires

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'userController': Unsatisfied dependency expressed through field 'userService'; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'userServiceImpl': Unsatisfied dependency expressed through field 'userRepository'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'userRepository': Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Not a managed type: class com.potholeapi.models.User
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:596) ~[spring-beans-5.1.8.RELEASE.jar:5.1.8.RELEASE]
    at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:90) ~[spring-beans-5.1.8.RELEASE.jar:5.1.8.RELEASE]
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessProperties(AutowiredAnnotationBeanPostProcessor.java:374) ~[spring-beans-5.1.8.RELEASE.jar:5.1.8.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1411) ~[spring-beans-5.1.8.RELEASE.jar:5.1.8.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:592) ~[spring-beans-5.1.8.RELEASE.jar:5.1.8.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:515) ~[spring-beans-5.1.8.RELEASE.jar:5.1.8.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:320) ~[spring-beans-5.1.8.RELEASE.jar:5.1.8.RELEASE]
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222) ~[spring-beans-5.1.8.RELEASE.jar:5.1.8.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:318) ~[spring-beans-5.1.8.RELEASE.jar:5.1.8.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199) ~[spring-beans-5.1.8.RELEASE.jar:5.1.8.RELEASE]
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:845) ~[spring-beans-5.1.8.RELEASE.jar:5.1.8.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:877) ~[spring-context-5.1.8.RELEASE.jar:5.1.8.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:549) ~[spring-context-5.1.8.RELEASE.jar:5.1.8.RELEASE]
    at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:140) ~[spring-boot-2.1.6.RELEASE.jar:2.1.6.RELEASE]
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:742) ~[spring-boot-2.1.6.RELEASE.jar:2.1.6.RELEASE]
    at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:389) ~[spring-boot-2.1.6.RELEASE.jar:2.1.6.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:311) ~[spring-boot-2.1.6.RELEASE.jar:2.1.6.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1213) ~[spring-boot-2.1.6.RELEASE.jar:2.1.6.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1202) ~[spring-boot-2.1.6.RELEASE.jar:2.1.6.RELEASE]
    at com.potholeapi.Application.main(Application.java:20) ~[classes/:na]
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:na]
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
    at java.base/java.lang.reflect.Method.invoke(Method.java:566) ~[na:na]
    at org.springframework.boot.maven.AbstractRunMojo$LaunchRunner.run(AbstractRunMojo.java:542) ~[na:na]
    at java.base/java.lang.Thread.run(Thread.java:834) ~[na:na]

Qu'est-ce que j'ai manqué dans la mise en place? De tous les didacticiels que j'ai consultés en ligne, le câblage automatique est censé fonctionner hors de la boîte


11 commentaires

(1) applicationContext.xml est obsolète avec Spring Boot. (2) Les noms de package doivent utiliser toutes les minuscules; comparer avec vos déclarations d'importation. (3) @ComponentScan et annotations de configuration similaires ne sont activés que lorsqu'ils sont présents sur @Configuration cours ( @SpringBootApplication comprend que). (4) Vous avez besoin de @EnableJpaRepositories sur votre configuration ( Application ).


J'ai implémenté les changements que vous avez suggérés et j'obtiens toujours le même résultat


Veuillez mettre à jour votre message d'erreur.


J'ai mis à jour le message d'erreur, je pense que c'est la même chose


D'accord, veuillez inclure votre fichier pom.xml ou build.gradle et montrer votre structure de répertoire (l'art ASCII est la manière habituelle). Vous pouvez également essayer @ComponentScan({"controllers", "repositories"}) @EntityScan("models") ; Je ne me souviens pas du haut de ma tête si @EnableJpaRepositories trouvera un type qui n'est pas déjà analysé par les composants (cela devrait, mais je ne suis pas sûr).


J'ai ajouté le pom.xml et mis à jour la structure pour supprimer le besoin du décorateur componentScan


Supprimez @EnableJpaRepositories , car cela est déjà activé par Spring Boot. Supprimez les dépendances hibernate et spring-data-jpa et ajoutez à la place la dépendance spring-boot-starter-data-jpa . De plus, la dépendance junit est déjà incluse dans la dépendance spring-boot-starter-test supprimez-la également (car il s'agit d'une version ancienne).


@ TylerB.Joudrey, Faites comme M. Deinum a dit, Et vérifiez ma réponse aussi.


J'ai suivi les suggestions faites et j'ai maintenant une nouvelle erreur, la question et les fichiers ont été mis à jour


@ TylerB.Joudrey J'ai modifié ma réponse. S'il vous plaît laissez-moi savoir si cela fonctionne ou non.


@ TylerB.Joudrey Avez-vous vérifié ma réponse?


3 Réponses :


1
votes

Il peut être avantageux pour vous de corriger la structure de votre package. Si votre application principale se trouve dans un package appelé my.base et que votre contrôleur est dans my.base.controllers, vous n'aurez pas à utiliser les analyses de composants. Ma suggestion dans l'état actuel est d'ajouter le package de référentiels à l'analyse des composants afin qu'il trouve le bean au moment de l'exécution.

@ComponentScan({"controllers", "reposistories"})


0 commentaires

2
votes

Premièrement, vous ne disposez pas d'une structure d'emballage de projet appropriée. Ensuite, vous n'avez pas de package de base. Spring mentionne toujours d'avoir un package de base pour les analyses de composants appropriées. Sans package de base, c'est une mauvaise pratique.

La meilleure pratique devrait être comme:

@ComponentScan({"main.controllers", "main.repositories"})
@EnableJpaRepositories("main.repositories")
@SpringBootApplication
public class Application {
  public static void main(String[] args) {
     SpringApplication.run(Application.class, args);
  }
}
  1. Xml - Configuration basée:

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

  2. Annotation ou configuration basée sur Java:

    @ComponentScan("com.project")

Deuxièmement, si vous avez ce type de paquet, au contraire, vous devez mentionner les noms de paquet séparément.

Vous devez le faire comme ceci:

  1. Xml - Configuration basée:

    <context:component-scan base-package="main.controllers, main.repositories" />

  2. Annotation ou configuration basée sur Java:

    @ComponentScan({"main.controllers", "main.repositories"})

De plus, vous avez un projet de démarrage à ressort. Donc, ce que vous faites est d'ajouter @ComponentScan dans la classe Application :

src
-main
--base package(x.x.x.) (for example : com.project)
---controllers
---models
---repositories
-resources


2 commentaires

vous bénisse pour fournir des réponses basées sur xml vs java-config vs annotations.


@granadaCoder Merci. Toujours là pour les gens :)



3
votes

Dans votre classe User , vous déclarez id avec le type int

@Service
public interface UserService {
    List<User> getUsers();
}

Mais dans l'interface du référentiel, vous avez déclaré Long

@Id
@Column(name = "id", unique = true)
private Long id;

Donc, dans la classe User , changez le type d'identifiant comme,

public interface UserRepository extends JpaRepository<User, Long> {}

Et éviter que votre nouvelle erreur, utilisez @Service annotation à UserService comme l' interface

@Id
@Column(name = "id", unique = true)
private int id;


0 commentaires