Tim
Tim

Reputation: 4274

How to use @ConfigProperty in a MapStruct mapper?

I need a @ConfigProperty in my Mapper. I cannot inject it, since the Mapper is an interface.

How can I solve this?

@ConfigProperty(name = "limit") // <- Does not work here
int limit;

@Mapping(target = "myTarget", source = "mySource", qualifiedByName = "myLimitMapper")
MyDto toDTO(Entity entity);

@Named(value = "myLimitMapper")
default int mapLimit(int number) {
    if (number >= limit) return limit;
    else return number;
}

Upvotes: 0

Views: 1054

Answers (1)

Jaims
Jaims

Reputation: 1575

I'm assuming you're using Quarkus, seeing the @ConfigProperty. But you can define an abstract mapper and use the cdi componentModel to let MapStruct create an @ApplicationScoped CDI bean. This is described in the dependency injection section of the MapStruct docs.

E.g. you have 2 classes to map:

public record UserModel(String name, int number) {}
public record UserDto(String name, int number) {}

In which limit is configured in the application.properties as 100.

Your mapper will look like:

@Mapper(componentModel = "cdi")
public abstract class UserMapper {

    @ConfigProperty(name = "limit")
    int limit;

    @Mapping(target = "number", source = "number", qualifiedByName = "myLimitMapper")
    abstract UserDto mapToDto(UserModel userModel);

    @Named(value = "myLimitMapper")
    int mapLimit(int number) {
        if (number >= limit) return limit;
        else return number;
    }
}

You could run this as a @QuarkusTest to verify:

@QuarkusTest
public class LimitTest {

    @Inject
    UserMapper userMapper;

    @Test
    public void testMapping() {
        UserModel userModel = new UserModel("John", 150);
        UserDto userDto = userMapper.mapToDto(userModel);
        assertEquals("John", userDto.name());
        assertEquals(100, userDto.number());
    }
}

Upvotes: 1

Related Questions