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>
Advertisement
Answer
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 :