MapStruct implementation is not working in Spring Boot Web Application

时间:2017-06-09 12:39:00

标签: spring-boot entity dto mapstruct

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 ?

6 个答案:

答案 0 :(得分:2)

将抽象类作为接口为我工作。

public interface UserAndEmployeeMapper {

答案 1 :(得分:2)

我也遇到了这个问题,将mapper从抽象类更改为接口对我来说不起作用。

我结束了:

  • 从映射器接口中删除INSTANCE属性
  • 创建实现接口的类,实现mappes方法
  • 在需要映射器的类中添加此类的实例作为@Autowired属性,并调用它。

WebAppMapper.java

    @Mapper(componentModel = "spring")
    public interface WebAppMapper {
        CatalogData createCatalogRequestToData(CreateCatalogRequest createCatalogRequest);
    }

WebAppMapperImpl.java

@Component
public class WebAppMapperImpl implements WebAppMapper {
    @Override
    public CatalogData createCatalogRequestToData(CreateCatalogRequest createCatalogRequest) {
        CatalogData catalogData = new CatalogData();
        catalogData.setId(createCatalogRequest.getId());
        catalogData.setName(createCatalogRequest.getName());
        return catalogData;
    }
}

CatalogController.java

@Autowired
WebAppMapper webAppMapper;

webAppMapper.createCatalogRequestToData(createCatalogRequest);

这对我有用。

答案 2 :(得分:1)

首先,public UserAndEmployeeMapper INSTANCE = Mappers.getMapper( UserAndEmployeeMapper.class );只应与默认组件模型一起使用,否则您可能无法正确初始化UserAndEmployeeMapper

UserAndEmployeeMapper中的LoginServiceImpl必须使用@Autowired进行注释,否则Spring无法注入,这就是null的原因。

我不知道你的包结构。如果包org中的Spring Boot应用程序类,那么它将获取UserAndEmployeeMapperImpl。否则,请确保弹簧配置选择UserAndEmployeeMapperImpl

如果上面的所有内容都已正确设置,并且您通过IDE启动应用程序,请确保target/generated-sources或Gradle的替代方案是您的来源的一部分并且已被选中。查看IDE Support以确保您已正确设置IDE的注释处理器发现。例如,IntelliJ不会使用您当前的设置调用MapStruct注释处理器,它不会从maven编译器中获取annotationProcessorPaths

答案 3 :(得分:1)

要使所有的映射器类都符合spring bean的标准,请在您的maven-compiler-plugin中添加以下compilerArgs。

<compilerArgs>
<arg>-Amapstruct.suppressGeneratorTimestamp=true</arg>
<arg>-Amapstruct.defaultComponentModel=spring</arg>
</compilerArgs> 

如果使用maven-processor-plugin添加以下选项

<options>                       
<mapstruct.suppressGeneratorTimestamp>
true
</mapstruct.suppressGeneratorTimestamp>                      
<mapstruct.defaultComponentModel>
spring
</mapstruct.defaultComponentModel>
</options>

答案 4 :(得分:0)

springfox-swagger2依赖关系会在排除旧版本的mapstruct后加载,并在开始生成源代码的pom.xml中添加特定版本的mapstruct依赖项

<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.2.2</version>
<exclusions>
 <exclusion>
 <groupId>org.mapstruct</groupId>
  <artifactId>mapstruct</artifactId>
 </exclusion>
</exclusions>

在地图结构依赖项下添加

<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-jdk8</artifactId>
<version>1.3.0.Beta1</version>

答案 5 :(得分:0)

就我而言,我认为该错误是由于build.gradle不完整造成的。

之前

dependencies {
    compile group: 'org.mapstruct', name: 'mapstruct-processor', version: '1.2.0.Final'
}

之后

apply plugin: 'net.ltgt.apt'

dependencies {
    compile group: 'org.mapstruct', name: 'mapstruct-processor', version: '1.2.0.Final'
    compile group: 'org.mapstruct', name: 'mapstruct-jdk8', version: '1.2.0.Final'
    apt 'org.mapstruct:mapstruct-processor:1.2.0.Final'
}


buildscript {
    repositories {
        mavenCentral()
        maven {
            url "https://plugins.gradle.org/m2/"
        }
    }
    dependencies {
        classpath("net.ltgt.gradle:gradle-apt-plugin:0.9")
    }
}

确保按照the docs.

中的说明正确配置了build.gradle