Reputation: 491
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
Upvotes: 16
Views: 246449
Reputation: 1
try reading the whole error until the end of it such that you may find a direction . I was also facing this error but reading more i found my error was not in the controller but in the optional method of the repository . So i fixed it and it ran successfully
Upvotes: 0
Reputation: 11
By creating this class you can resolve the Error
@Configuration
public class AppConfig {
@Bean
public ModelMapper modelMapper() {
try {
return new ModelMapper();
} catch (Exception ex) {
throw new RuntimeException("Error creating ModelMapper bean", ex);
}
}
}
Upvotes: 0
Reputation: 217
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"})
Upvotes: 2
Reputation: 3086
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();
}
Upvotes: 13
Reputation: 16559
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
Xml - Based config :
<context:component-scan base-package="com.project" />
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 :
Xml - Based config :
<context:component-scan base-package="main.controllers, main.repositories" />
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);
}
}
Upvotes: 4