MapStruct's generated mapper doesn't map any properties
My MapStruct mapper doesn't work. For some reason, getters/setters are not included in the mapper method bodies (the mapper implementation *is* generated). It simply calls the no-args and returns the result.
May have to do with Mapstruct for some reason not seeing the generated getters/setters – even though the binding dependency is in place.
I need my mappers to be `@Component`s in production, so I set `componentModel` to `spring`.
Here's an MRE (and a failing test)
```java
package com.example.demo.data;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
public class Cat {
private String name;
}
```
```java
package com.example.demo.data;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
public class CatDto {
private String name;
}
```
```java
package com.example.demo.mapper;
import com.example.demo.data.Cat;
import com.example.demo.data.CatDto;
import org.mapstruct.Mapper;
@Mapper(componentModel = "spring")
public interface CatMapper {
Cat toCat(CatDto cat);
}
```
```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 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>3.3.5</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>demo</name>
<description>Demo project for MapStruct</description>
<properties>
<java.version>17</java.version>
<mapstruct.version>1.6.3</mapstruct.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct</artifactId>
<version>${mapstruct.version}</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok-mapstruct-binding</artifactId>
<version>0.2.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<annotationProcessorPaths>
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
</path>
<path>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>${mapstruct.version}</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
```
```java
package com.example.demo;
import com.example.demo.data.Cat;
import com.example.demo.data.CatDto;
import com.example.demo.mapper.CatMapper;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import static org.junit.jupiter.api.Assertions.assertEquals;
@SpringBootTest
class DemoApplicationTests {
@Autowired
private CatMapper catMapper;
@Test
void contextLoads() {
CatDto catDto = new CatDto();
catDto.setName("Kitty");
Cat cat = catMapper.toCat(catDto);
assertEquals(catDto.getName(), cat.getName()); // fails: expected "Kitty", actual null
}
}
```
MapStruct's implementation in full:
```java
package com.example.demo.mapper;
import com.example.demo.data.Cat;
import com.example.demo.data.CatDto;
import javax.annotation.processing.Generated;
import org.springframework.stereotype.Component;
@Generated(
value = "org.mapstruct.ap.MappingProcessor",
date = "2024-11-14T19:21:15+0300",
comments = "version: 1.6.3, compiler: javac, environment: Java 17.0.13 (Amazon.com Inc.)"
)
@Component
public class CatMapperImpl implements CatMapper {
@Override
public Cat toCat(CatDto cat) {
if ( cat == null ) {
return null;
}
Cat cat1 = new Cat();
return cat1;
}
@Override
public CatDto toDto(Cat cat) {
if ( cat == null ) {
return null;
}
CatDto catDto = new CatDto();
return catDto;
}
}
```
IntelliJ IDEA Community 2024.2.4. Here are my annotation processor settings (I didn't manually configure them):
[![enter image description here][1]][1]
It is very likely to be an IntelliJ issue. I compiled it with Maven, and the generated implementation was generated alright.
It would be funny if it turned out to have to do with "p" ("projectlombok") coming after "m" ("mapstruct") in the English alphabet. I guess the annotation processors are applied in the classpath encounter order by default which is, in turn, natural
How is it supposed to be resolved? How do I make the order of annotation processors match the order defined in my pom (preferrable, automatically)?
[1]: https://i.sstatic.net/pzKjGbUf.png
Please sign in to leave a comment.
Hello, could you please provide a minimal sample project so I can reproduce the issue without including your sensitive code? It maybe required to create an issue report.
Please upload them to https://uploads.jetbrains.com and provide the upload id here.
Didn't I? You just need to paste the snippets
Hi Nad, I saw your original post at https://stackoverflow.com/questions/79189673/mapstructs-generated-mapper-doesnt-map-any-properties and the source code is at here: https://github.com/eugenp/tutorials/tree/master/mapstruct-2
I'm using IDEA 2024.3 and all the test passed, please try with IDEA 2024.3 to see it works for you too.