Mapstruct: Fluent setters starting with is are not correctly handled

Created on 18 Sep 2018  Â·  7Comments  Â·  Source: mapstruct/mapstruct

I am having an issue with MapStruct 1.3.0-Beta1 when used with Lombok Builders and fields that begin with 'is'.

I get an error like
BookMapper.java:[12,10] Unknown property "isbn" in result type api.Book. Did you mean "null"?

I recreated the issue in a smaller example. Here are the 2 bean classes that I am mapping between.

@Value
@Builder
public class BookDto {
    String bookIsbn;
    String title;
}
@Value
@Builder
public class Book {
    String isbn;
    String title;
}

The Lombok generated code, has getIsbn(), but the Builder uses fluent style setters isbn("123")

@Mapper
public interface BookMapper {
    @Mapping(source = "bookIsbn", target = "isbn")
    Book dtoToBook(BookDto bookDto);
}

It does work if I change the mapping line to remove the leading is from the target.

@Mapping(source = "bookIsbn", target = "bn")

In real code, I also had this mapping, which seems to imply a very different meaning.
issueDate → sueDate

bug

All 7 comments

In real code, I also had this mapping, which seems to imply a very different meaning.

:smile: MapStruct seems to have an opinion..

MapStruct probably assumes bean-convention (getters/setters) for the lombok case. However, it should possibly assume fluent getters and setters by default. Have a look here for how this is solved for the immutable framework..

You can always define your own strategy by means of the SPI interface. Perhaps its good that MapStruct scans for lombok annotations and applies a FluentAccessorNamingStrategy. Perhaps we should even rename the ImmutableAccessorNamingStrategy to FluentAccessorNamingStrategy and apply it in both the Lombok and Immutable cases. @filiphr : what do you think about that?

@sjaakd the DefaultAccessorNamingStrategy actually works with fluent setters we should not do anything special with those and there is nothing that Lombok or Immutables do bad.

Have a look here for how this is solved for the immutable framework..

That solved another problem for Immutables, not this one

The problem is actually in

https://github.com/mapstruct/mapstruct/blob/master/processor/src/main/java/org/mapstruct/ap/spi/DefaultAccessorNamingStrategy.java#L157-L165

So if we first check if the getterOrSetterMethod is a fluent setter and return the method name. The only caveat I think is that if someone uses fluent setters and use setName. Having said that, maybe we should apply the following:

  • If it starts with set it is a normal setter, remove that and return
  • If is is fluent setter return the method name
  • decapitalize like we do now

Just an idea without diving into the code:

The line mentioned by @filiphr checks if the method starts with is/get/set. Couldn't we just check additionally if the character after is/get/set is uppercase? Could this already solve the issue without having other side effects?

Thanks for reporting this @duanemay we have fixed it and integrated into master. I have renamed the issue as it was a general problem for fluent setters and not just Lombok.

The same behavior is observed for newly added support builders. The case is that field having a name "settlement" is set via a builder method having the same name. But mapstruct refuses to pick up the method, we have to work around this issue as:
@Mapping(target = "tlement", ...)
Could it be caused by the same issue? Or is it smth new?

any news on this item?

@msymonov, it seems like we've missed your message (please open new issues instead of commenting on old ones). In any case there is #1799 which is exactly what you said. This is clearly a bug and would be fixed in 1.4

Was this page helpful?
0 / 5 - 0 ratings