5

Is it possible to set a value from a field from the application.properties file?

I am looking for something like

    @Mapping(target="version", expression="${application.version}")
    StateDto stateToStateDto(State state);

where application.version=v1 is from the application.properties file.

Scala
  • 116
  • 2
  • 7

4 Answers4

5

Consider a "util service" like:

@Service
public class PropertyService {

  @org.springframework.beans.factory.annotation.Value("${application.version}")
  private String appVersion;

  // accessors, more properties/stuff..
}

Then you can define your Mapping like:

@Mapper(// ..., ...
   componentModel = "spring")
public abstract class StateMapper {

  @Autowired
  protected PropertyService myService;

  @org.mapstruct.Mapping(target="version", expression="java(myService.getAppVersion())")
  public abstract StateDto stateToStateDto(State state);
  // ...
}

See also:


My minimal solution @github

xerx593
  • 12,237
  • 5
  • 33
  • 64
2

As far as my knowledge goes, this is not possible. Mapstruct analyses the @Mapping annotation in compile time. And the annotation parameters require constants. So getting them from a file would not be possible.

You can always implement something in MapStruct that fulfills your needs. But I would go with a simple self-implemented mapper where you take the value from your version field in runtime from the environment.

EDIT:

This is possible. See this answer.

Renis1235
  • 4,116
  • 3
  • 15
  • 27
1

This is not possible through MapStruct. However, a feature could be raised that would support some custom expression language that would use Spring @Value and inject that.

e.g.

@Mapping(target="version", expression="springValue(${application.version})")
StateDto stateToStateDto(State state);

and then MapStruct will generate something like:

@Component
public class StateMapperImpl {

    @Value("${application.version}")
    private String version;


    // ...
}
Filip
  • 19,269
  • 7
  • 51
  • 60
  • Downvoted for the statment "This is not possible through MapStruct", because this **is** possible, see my answer. – Honza Zidek Apr 18 '23 at 15:34
1

The solution is very simple. You just use abstract class instead of interface, then you can use directly the @Value annotation.

@Mapper(componentModel = "spring")
public abstract class StateMapper {
    @Value("${application.version}")
    protected String applicationVersion;

    @Mapping(target = "version", expression = "java(this.applicationVersion)")
    public abstract StateDto map(State state);
}
Honza Zidek
  • 9,204
  • 4
  • 72
  • 118