I need to use Mapstruct and this error is comming up.
*APPLICATION FAILED TO START Description: Field userMapper in com.mycomp.myappapi.service.UserService required a bean of type 'com.mycomp.myappapi.mapper.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.mycomp.myappapi.mapper.UserMapper' in your configuration.*
Since there's this line in myappapiApplication.java
, understand it should be able to find UserMapper.java
. But for some reason it's not.
@ComponentScan(basePackages = {"com.mycomp.*"})
Also, it is not autogenerating the mapstruct implementation classes in \target
folder.
package com.mycomp.myappapi;
@SpringBootApplication
@EntityScan(basePackages = {"com.mycomp.myappapi.model"})
@ComponentScan(basePackages = {"com.mycomp.*"})
@EnableJpaRepositories(basePackages = {"com.mycomp.myappapi.repository"})
@EnableTransactionManagement
@EnableWebMvc
@RestController
@EnableAutoConfiguration
public class myappapiApplication {
public static void main(String[] args) {
SpringApplication.run(myappapiApplication.class, args);
}
}
package com.mycomp.myappapi.mapper;
@Mapper(componentModel = "Spring")
public interface UserMapper {
User UserRequestDTOtoUser(UserRequestDTO userRequestDTO);
UserResponseDTO UserToUserResponseDTO(User user);
}
package com.mycomp.myappapi.service;
...
@Service
@Transactional
public class UserService {
@Autowired
private UserMapper userMapper;
@Autowired
private UserRepository userRepository;
public UserResponseDTO saveUser(UserRequestDTO userRequestDTO) {
User user = userMapper.UserRequestDTOtoUser(userRequestDTO);
...
User savedUser = userRepository.save(user);
UserResponseDTO userResponseDTO = userMapper.UserToUserResponseDTO(savedUser);
return userResponseDTO;
}
}
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 http://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.7.7</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.mycomp.myappapi</groupId>
<artifactId>myappapi</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<name>myappapi</name>
<description>aaa</description>
<properties>
<java.version>11</java.version>
<org.mapstruct.version>1.5.2.Final</org.mapstruct.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-rest</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.25</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct</artifactId>
<version>${org.mapstruct.version}</version>
</dependency>
</dependencies>
<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>
<!--<version>3.8.1</version>-->
<version>${maven-compiler-plugin.version}</version>
<configuration>
<source>11</source> <!-- depending on your project -->
<target>11</target> <!-- depending on your project -->
<annotationProcessorPaths>
<path>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>${org.mapstruct.version}</version>
</path>
<!-- other annotation processors -->
</annotationProcessorPaths>
</configuration>
</plugin>
</plugins>
</build>
</project>
CodePudding user response:
Try using spring
instead of Spring
. The documentation does not have an upper case. Even better: add the config to your pom.xml, then you don't have to specify the componentModel
for every mapper:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<!--<version>3.8.1</version>-->
<version>${maven-compiler-plugin.version}</version>
<configuration>
<source>11</source> <!-- depending on your project -->
<target>11</target> <!-- depending on your project -->
<annotationProcessorPaths>
<path>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>${org.mapstruct.version}</version>
</path>
<!-- other annotation processors -->
</annotationProcessorPaths>
<compilerArgs>
<compilerArg>-Amapstruct.defaultComponentModel=spring</compilerArg>
</compilerArgs>
</configuration>
</plugin>
CodePudding user response:
according to this guide: https://www.baeldung.com/mapstruct#2-inject-spring-components-into-the-mapper
Sometimes, we'll need to utilize other Spring components inside our mapping logic. In this case, we have to use an abstract class instead of an interface
try to change UserMapper
into an abstract class.