Issue
I am new to spring, when i try to do the mvn clean install
of my project this problem appears:
Error
***************************
APPLICATION FAILED TO START
***************************
**Description**:
Field userService in com.example.accessingdatamysql.rest.MainController required a bean of type 'com.example.accessingdatamysql.service.UserService' that could not be found.
The injection point has the following annotations:
- @org.springframework.beans.factory.annotation.Autowired(required=true)
Action:
Consider defining a bean of type 'com.example.accessingdatamysql.service.UserService' in your configuration.
The problem is that in the MainController
there is the import of "UserService":
package com.example.accessingdatamysql.rest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import com.example.accessingdatamysql.model.dto.UserDto;
import com.example.accessingdatamysql.service.UserService;
@RestController
public class MainController {
@Autowired
private UserService userService;
@Transactional
@PostMapping(path="/demo/add")
public @ResponseBody String addNewUser (@RequestParam String name
, @RequestParam String email,@RequestParam String surname)
{
UserDto n = new UserDto();
n.setName(name);
n.setSurname(surname);
n.setEmail(email);
userService.create(n);
return "Saved";
}
@GetMapping("/demo/first")
public UserDto one(@RequestParam String name) {
System.out.print(name);
return userService.findFirstByName(name);
}
}
It is probably a trivial thing but I can not bypass the problem, below I insert "UserService" and the MainStart
UserService.java
package com.example.accessingdatamysql.service;
import com.example.accessingdatamysql.model.dto.UserDto;
public interface UserService {
UserDto findFirstByName(String name);
void create(UserDto user);
}
UPDATE : I insert the UserServiceImpl and the new main and Mapper, with the new error.
UserServiceImpl.java
package com.example.accessingdatamysql.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.example.accessingdatamysql.model.dto.UserDto;
import com.example.accessingdatamysql.model.entity.UserEntity;
import com.example.accessingdatamysql.model.repo.UserRepository;
import com.example.accessingdatamysql.util.UserMapper;
@Service
public class UserServiceImpl implements UserService{
@Autowired
private UserRepository userRepository;
@Autowired
UserMapper mapper;
@Override
public UserDto findFirstByName(String name) {
UserEntity entity = userRepository.findFirstByName(name);
return mapper.toDtoMapper(entity);
}
@Override
public void create(UserDto user) {
UserEntity entity = mapper.toEntityMapper(user);
userRepository.create(entity);
}
}
AccessingDataMysqlApplication.java
package com.example;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.context.annotation.ComponentScan;
@SpringBootApplication(scanBasePackages = { "com.example.accessingdatamysql",
"com.example.accessingdatamysql.util"})
public class AccessingDataMysqlApplication {
public static void main(String[] args) {
SpringApplication.run(AccessingDataMysqlApplication.class, args);
}
}
UserMapper.java
package com.example.accessingdatamysql.util;
import org.mapstruct.Mapper;
import com.example.accessingdatamysql.model.dto.UserDto;
import com.example.accessingdatamysql.model.entity.UserEntity;
@Mapper (componentModel = "spring")
public interface UserMapper {
UserEntity toEntityMapper (UserDto user);
UserDto toDtoMapper (UserEntity userEntity);
}
New Error:
***************************
APPLICATION FAILED TO START
***************************
Description:
Field mapper in com.example.accessingdatamysql.service.UserServiceImpl required a bean of type 'com.example.accessingdatamysql.util.UserMapper' that could not be found.
The injection point has the following annotations:
- @org.springframework.beans.factory.annotation.Autowired(required=true)
Action:
Consider defining a bean of type 'com.example.accessingdatamysql.util.UserMapper' in your configuration.
POM
<?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>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.4.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>accessingdatamysql</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>project</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct</artifactId>
<version>1.3.1.Final</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
Solution
Annotate your UserService class implementation [like UserServiceImpl.java
] with @Service
or @Component
. Also make sure this class is located in a sub-package.
This is your main class package : com.example.accessingdatamysql
Your UserService class and all other classes should be kept in a package like : com.example.accessingdatamysql.xxxxxx
. Ensure this strategy is followed.
Plus remove the unnecessary annotations on your main class. The @SpringBootApplication annotation is equivalent to using the below 3 : :
- @Configuration,
- @EnableAutoConfiguration and
- @ComponentScan with attributes.
This will be enough :
@SpringBootApplication (scanBasePackages = "com.example.accessingdatamysql")
And do not keep a gap when you autowire any bean injection. This does not cause any harm. But your code should be properly organized and indentation done.
Also replace below :
@Autowired
private UserService userService;
With this :
@Autowired
private UserService userService;
UPDATE-1
Do a maven clean install after you fix your spring boot configurations.
mvn clean install
UPDATE-2
Your bean for Mapper does not fully qualify for a spring bean. You need to compile your project with the below plugin (see the 2nd plugin I have used).
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
<annotationProcessorPaths>
<path>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>1.3.1.Final</version>
</path>
</annotationProcessorPaths>
<compilerArgs>
<compilerArg>
-Amapstruct.defaultComponentModel=spring
</compilerArg>
</compilerArgs>
</configuration>
</plugin>
</plugins>
</build>
Then you need to fix your UserDto.java as below (change the type of timestamp variable else Mapper will fail):
import java.sql.Timestamp;
private Timestamp timestamp;
public Timestamp getTimestamp() {
return timestamp;
}
public void setTimestamp(Timestamp timestamp) {
this.timestamp = timestamp;
}
Your main class should only have this : @SpringBootApplication (scanBasePackages = "com.example.accessingdatamysql")
and no other annotation.
Then save your project. And Then run : mvn clean install -X
Make your package structure like this :
And your classes arranged in the below way :
Answered By - Som
Answer Checked By - David Goodson (JavaFixing Volunteer)