Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MapStruct implementation is not working in Spring Boot Web Application

I am a newbie to Spring Boot and MapStruct Tool.

Earlier, A Project(written by other team using these technologies) is not starting up. Then, I had made some changes in Mapper Abstract Class but now mapper object is coming as null on application startup.

Mapper Abstract Class:

@Mapper(componentModel = "spring")
public abstract class UserAndEmployeeMapper {

    public UserAndEmployeeMapper INSTANCE = Mappers.getMapper( UserAndEmployeeMapper.class );

    @Mapping(source = "username", target = "name")
    @Mapping(source = "ssn", target = "ssn", defaultValue = "xxxxxx" )
    @Mapping(target = "salary", constant = "34.67")
    @Mapping(target = "dob", dateFormat = "dd/MM/yyyy", constant = "10/12/2002")
    public abstract Employee mapToEmployee(User user);

    public abstract List<Employee> mapToEmployee(List<User> users);

    @Mapping(source = "name", target = "username")
    public abstract User mapToUser(Employee employee);

    public abstract List<User> mapToUser(List<Employee> employees);

}

LoginServiceImpl class

@Service("loginService")
public class LoginServiceImpl implements LoginService{

    private static final AtomicLong counter = new AtomicLong();

    @Autowired
    private EmployeeDao employeeDao;

    private UserAndEmployeeMapper userAndEmployeeMapper;
...

}

pom.xml

<build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>${maven.compiler.plugin.version}</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                    <annotationProcessorPaths>
                        <path>
                            <groupId>org.mapstruct</groupId>
                            <artifactId>mapstruct-processor</artifactId>
                            <version>${mapstruct.jdk8.version}</version>
                        </path>
                    </annotationProcessorPaths>
                </configuration>
            </plugin>
</build>

After I added @Autowired in LoginServiceImpl, application is not starting and following error log is showing

***************************
APPLICATION FAILED TO START
***************************

Description:

Field userAndEmployeeMapper in org.service.impl.LoginServiceImpl required a bean of type 'org.mapper.UserAndEmployeeMapper' that could not be found.


Action:

Consider defining a bean of type 'org.mapper.UserAndEmployeeMapper' in your configuration.

Any suggestions ?

like image 857
Ankit Avatar asked Jun 09 '17 12:06

Ankit


People also ask

How does MapStruct generate implementation?

MapStruct is an open-source Java-based code generator which creates code for mapping implementations. It uses annotation-processing to generate mapper class implementations during compilation and greatly reduces the amount of boilerplate code which would regularly be written by hand.

What is spring boot MapStruct?

What is it? MapStruct is a code generator that greatly simplifies the implementation of mappings between Java bean types based on a convention over configuration approach. The generated mapping code uses plain method invocations and thus is fast, type-safe and easy to understand.

Does MapStruct work with Lombok?

Yes, as of MapStruct 1.2. 0. Beta1 and Lombok 1.16.

How do I use MapStruct plugin in eclipse?

Installation. Drag the following icon into your running Eclipse workspace: Alternatively, you can obtain the MapStruct Eclipse Plugin from the Eclipse Marketplace. For more information and for installing the latest Snapshot version, visit the plugins GitHub project.


1 Answers

First of all, public UserAndEmployeeMapper INSTANCE = Mappers.getMapper( UserAndEmployeeMapper.class ); should only be used with the default component model, otherwise you risk to have the UserAndEmployeeMapper not correctly initialized.

The UserAndEmployeeMapper in your LoginServiceImpl must be annotated with @Autowired, otherwise it cannot be injected by Spring, and that's why it is null.

I don't know your package structure. If your Spring Boot application class in the package org then it will pick up the UserAndEmployeeMapperImpl. Otherwise make sure that the spring configuration picks up the UserAndEmployeeMapperImpl.

If everything from above is correctly setup and you are starting the application via an IDE make sure that target/generated-sources or the alternative for Gradle is part of your sources and is picked up. Have a look at the IDE Support to make sure that you have correctly setup the Annotation processor discovery for an IDE. For example, IntelliJ will not invoke the MapStruct Annotation Processor with your current setup, it doesn't pick up the annotationProcessorPaths from the maven compiler.

like image 77
Filip Avatar answered Oct 22 '22 22:10

Filip