Home > Enterprise >  Mapstruct - Field required a bean of type that could not be found
Mapstruct - Field required a bean of type that could not be found

Time:01-31

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

  • Related