#3649·mapstruct

Support record-style getters

Author: AkatrojCreated Jul 25, 2024Updated Aug 20, 2026
Labelsfeature

Expected behavior

Hello, I tried using a mapper that accepts an interface with record-like getters (field() instead of getField()) as an argument and MapStruct did not generate the correct code (left the fields uninitialized instead of using the getter). I provided code example below.

Actual behavior

No response

Steps to reproduce the problem

mapper code:

java
@Mapper
public interface TestMapper {
    TestMapper INSTANCE = Mappers.getMapper(TestMapper.class);

    SomeModelWithUserId fromUserIdAndSomeOtherData(UserIdProvider userIdProvider, String someOtherData);
}

target model:

java
public record SomeModelWithUserId(
    long userId,
    String someOtherData
) {
}

UserIdProvider Interface:

java
public interface UserIdProvider {
    long userId();
}

record implementing UserIdProvider :

java
public record User(
    long userId
) implements UserIdProvider {
}

example usage of the mapper

java
System.out.println(
    TestMapper.INSTANCE.fromUserIdAndSomeOtherData(
        new User(1),
        "someOtherData"
    )
);

The generated code should use UserIdProvider::userId method to set the userId, but it does not. Instead, it leaves userId uninitialized (long userId = 0L;) and gives this warning during build.

TestMapper.java:10: warning: Unmapped target property: "userId".
    SomeModelWithUserId fromUserIdAndSomeOtherData(UserIdProvider userIdProvider, String someOtherData);

I believe this is a bug, because:

  • If the UserIdProvider interface had a getUserId() method instead of userId(), it would work:
java
public interface UserIdProvider {
    long userId();

    // with this, mapstruct generates correct code
    default long getUserId() {
        return userId();
    }
}
  • if the type of the argument in the mapper was a record implementing UserIdProvider, and not UserIdProvider interface itself, it would work (using the userId() record getter):
java
@Mapper
public interface TestMapper {
    TestMapper INSTANCE = Mappers.getMapper(TestMapper.class);

    //works
    SomeModelWithUserId fromUserIdAndSomeOtherData(User user, String someOtherData);
}

MapStruct Version

1.5.5.Final and 1.6.0RC1