How to fix: Error creating bean with name : Unsatisfied dependency expressed through field

55,957

Solution 1

In your User class you declare id with int type

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

But in the repository interface, you declared Long

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

So, in User class change type of id like,

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

And avoid your new error, use @Service annotation at UserService interface like

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

Solution 2

First, you don't have an appropriate project packaging structure. Then, you don't have a base package. Spring always mentions to have a base package for proper component scans. Without base package, it's a bad practice.

The best practice should be like :

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

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

  2. Annotation or Java- based config :

    @ComponentScan("com.project")

Secondly, if you have these kind of package, on a contrary, you have to mention package names separately.

You have to do it like this :

  1. Xml - Based config :

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

  2. Annotation or Java- based config :

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

Moreover, you are having a spring-boot project. So what you do is add @ComponentScan in the Application class :

@ComponentScan({"main.controllers", "main.repositories"})
@EnableJpaRepositories("main.repositories")
@SpringBootApplication
public class Application {
  public static void main(String[] args) {
     SpringApplication.run(Application.class, args);
  }
}

Solution 3

It may be beneficial for you to fix your package structure. If your main application is at a package called my.base and your controller is at my.base.controllers then you won't have to use the component scans. My suggestion in the current state is to add the repositories package to the component scan so it will find the bean at runtime.

@ComponentScan({"controllers", "reposistories"})
Share:
55,957

Related videos on Youtube

Tyler B. Joudrey
Author by

Tyler B. Joudrey

Updated on May 29, 2021

Comments

  • Tyler B. Joudrey
    Tyler B. Joudrey over 1 year

    I am trying to set up a spring rest api using hibernate. When trying to use the userRespository I set up I am getting this error

    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]
    

    Here are the Model, Controller and Application Files

    Model

    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;
        }
    }
    

    Controller

    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();
        }
    }
    

    Repository

    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> {}
    

    Service

    package com.potholeapi.services;
    import com.potholeapi.models.User;
    import java.util.List;
    import java.util.Optional;
    public interface UserService {
        List<User> getUsers();
    }
    

    ServiceImpl

    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;
        }
    }
    

    Application

    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);
        }
    }
    

    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 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>
    

    application.properties

    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
    

    directory structure

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

    What have I missed in setting this up? From all of the tutorials i have looked at online autowired is supposed to work oujt of the box

    • chrylis -cautiouslyoptimistic-
      chrylis -cautiouslyoptimistic- about 3 years
      (1) applicationContext.xml is obsolete with Spring Boot. (2) Package names should use all lowercase; compare with your import statements. (3) @ComponentScan and similar configuration annotations are only activated when present on @Configuration classes (@SpringBootApplication includes that). (4) You need @EnableJpaRepositories on your configuration (Application).
  • granadaCoder
    granadaCoder over 2 years
    bless you for providing xml vs java-config vs annotation based answers.
  • Anish B.
    Anish B. over 2 years
    @granadaCoder Thanks. Always there for people :)

Related