title: MapStruct does not detect setters in builder
body: <p>I am building a simple REST service using spring. I separated my entities from DTOs and I made the DTOs immutable using <a href="https://immutables.github.io/" rel="nofollow noreferrer">Immutables</a>. I needed mapping between DTOs and DAOs, so I chose <a href="http://mapstruct.org/" rel="nofollow noreferrer">MapStruct</a>. The Mapper is not able to detect the setters I have defined in my DAOs.</p>
  
  <p>The problem is exactly similar to <a href="https://stackoverflow.com/questions/38770813/mapping-an-object-to-an-immutable-object-with-builder-using-immutables-annotati">this question</a>. This question does not have an accepted answer and I have tried all of the suggestions in that question and they don't work. I don't want to try <a href="https://stackoverflow.com/a/44825324/4054389">this answer</a> because I feel it defeats the purpose for which I am using Immutables. @marc-von-renteln summarizes this reason nicely in the comment <a href="https://stackoverflow.com/questions/38770813/mapping-an-object-to-an-immutable-object-with-builder-using-immutables-annotati#comment76722544_44825324">here</a></p>
  
  <p>I tried the <a href="https://stackoverflow.com/a/48228965/4054389">answer</a> provided by @tobias-schulte. But that caused a different problem. In the Mapper class in the answer, trying to return Immutable*.Builder from the mapping method throws an error saying the Immutable type cannot be found.</p>
  
  <p>I have exhaustively searched issues logged against MapStruct and Immutables and I haven't been able to find a solution. Unfortunately there are hardly few examples or people using a combination of MapStruct and Immutables. The <a href="https://github.com/mapstruct/mapstruct-examples" rel="nofollow noreferrer">mapstruct-examples</a> repository also doesn't have an example for working with Immutables.</p>
  
  <p>I even tried defining separate Mapper interfaces for each of the DtTOs (like UserStatusMapper). I was only making it more complicated with more errors.</p>
  
  <p>I have created a sample spring project to demonstrate the problem.
  <a href="https://github.com/deepaks829/demo" rel="nofollow noreferrer">GitHub Repo Link</a>. This demo app is almost same as the REST service I am creating. All database (spring-data-jpa , hibernate) stuff is removed and I am using mock data.
  If you checkout the project and run the demo-app you can make two API calls.</p>
  
  <p>GetUser:
  Request:
  <a href="http://localhost:8080/user/api/v1/users/1" rel="nofollow noreferrer">http://localhost:8080/user/api/v1/users/1</a>
  Response:</p>
  
  <pre><code>{
      "id": 0,
      "username": "TestUser",
      "email": "TestUser@demo.com",
      "userStatus": {
          "id": 1,
          "status": 1,
          "statusName": "Active"
      }
  
  </code></pre>
  
  <p>Createuser: PROBLEM HERE
  <a href="http://localhost:8080/user/api/v1/users/create" rel="nofollow noreferrer">http://localhost:8080/user/api/v1/users/create</a>
  Sample Input:</p>
  
  <pre><code>{
      "username": "TestUser",
      "email": "TestUser@demo.com",
      "userStatus": {
          "id": 1,
          "status": 1,
          "statusName": "Active"
      }
  }
  </code></pre>
  
  <p>Response:</p>
  
  <pre><code>{
      "timestamp": "2019-04-28T09:29:24.933+0000",
      "status": 500,
      "error": "Internal Server Error",
      "message": "Type definition error: [simple type, class com.immutablesmapstruct.demo.dto.model.ImmutableUserDto$Builder]; nested exception is com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of `com.immutablesmapstruct.demo.dto.model.ImmutableUserDto$Builder`, problem: Cannot build UserDto, some of required attributes are not set [username, email, userStatus]\n at [Source: (PushbackInputStream); line: 9, column: 1]",
      "path": "/user/api/v1/users/create"
  }
  </code></pre>
  
  <p>Below are important pieces of code related to problem:</p>
  
  <p><em>Daos:</em>
  <em>1. UserDao</em></p>
  
  <pre><code>public class User {
  
      // Primary Key. Something that is annotated with @Id
      private int id;
      private String username;
      private String email;
      private UserStatus userStatus;
  
      private User(Builder builder) {
          id = builder.id;
          username = builder.username;
          email = builder.email;
          userStatus = builder.userStatus;
      }
  
      public static Builder builder() {
          return new Builder();
      }
  
      public int getId() {
          return id;
      }
  
      public String getUsername() {
          return username;
      }
  
      public String getEmail() {
          return email;
      }
  
      public UserStatus getUserStatus() {
          return userStatus;
      }
  
      public static final class Builder {
          private int id;
          private String username;
          private String email;
          private UserStatus userStatus;
  
          private Builder() {
          }
  
          public Builder setId(int id) {
              this.id = id;
              return this;
          }
  
          public Builder setUsername(String username) {
              this.username = username;
              return this;
          }
  
          public Builder setEmail(String email) {
              this.email = email;
              return this;
          }
  
          public Builder setUserStatus(UserStatus userStatus) {
              this.userStatus = userStatus;
              return this;
          }
  
          public User build() {
              return new User(this);
          }
  
  </code></pre>
  
  <p><em>2. UserStatusDao:</em></p>
  
  <pre><code>package com.immutablesmapstruct.demo.dao.model;
  
  /**
   * Status of user.
   * Example: Active or Inactive
   */
  public class UserStatus {
      // Primary Key. Something that is annotated with @Id
      private int id;
      // A value of 1 or 0
      private int status;
      // Active , InActive
      private String statusName;
  
      private UserStatus(Builder builder) {
          id = builder.id;
          status = builder.status;
          statusName = builder.statusName;
      }
  
      public static Builder builder() {
          return new Builder();
      }
  
      public int getId() {
          return id;
      }
  
      public int getStatus() {
          return status;
      }
  
      public String getStatusName() {
          return statusName;
      }
  
      public static final class Builder {
          private int id;
          private int status;
          private String statusName;
  
          private Builder() {
          }
  
          public Builder setId(int id) {
              this.id = id;
              return this;
          }
  
          public Builder setStatus(int status) {
              this.status = status;
              return this;
          }
  
          public Builder setStatusName(String statusName) {
              this.statusName = statusName;
              return this;
          }
  
          public UserStatus build() {
              return new UserStatus(this);
          }
      }
  }
  </code></pre>
  
  <p><em>DTOs</em>
  <em>1. UserDto:</em></p>
  
  <pre><code>package com.immutablesmapstruct.demo.dto.model;
  
  import com.fasterxml.jackson.annotation.JsonProperty;
  import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
  import com.fasterxml.jackson.databind.annotation.JsonSerialize;
  import org.immutables.value.Value;
  
  @Value.Immutable
  @Value.Style(defaults = @Value.Immutable(copy = false), init = "set*")
  @JsonSerialize(as = ImmutableUserDto.class)
  @JsonDeserialize(builder = ImmutableUserDto.Builder.class)
  public abstract class UserDto {
  
      @Value.Default
      @JsonProperty
      public int id() {
          return 0;
      }
  
      @JsonProperty
      public abstract String username();
  
      @JsonProperty
      public abstract String email();
  
      @JsonProperty
      public abstract UserStatusDto userStatus();
  
  </code></pre>
  
  <p><em>2. UserStatusDto:</em></p>
  
  <pre><code>package com.immutablesmapstruct.demo.dto.model;
  
  import com.fasterxml.jackson.annotation.JsonProperty;
  import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
  import com.fasterxml.jackson.databind.annotation.JsonSerialize;
  import org.immutables.value.Value;
  
  @Value.Immutable
  @Value.Style(defaults = @Value.Immutable(copy = false), init = "set*")
  @JsonSerialize(as = ImmutableUserStatusDto.class)
  @JsonDeserialize(builder = ImmutableUserStatusDto.Builder.class)
  public abstract class UserStatusDto {
  
      @JsonProperty
      public abstract int id();
  
      @JsonProperty
      public abstract int status();
  
      @JsonProperty
      public abstract String statusName();
  
  }
  </code></pre>
  
  <p>MapStruct UserMapper:</p>
  
  <pre><code>package com.immutablesmapstruct.demo.dto.mapper;
  
  import com.immutablesmapstruct.demo.dao.model.User;
  import com.immutablesmapstruct.demo.dao.model.UserStatus;
  import com.immutablesmapstruct.demo.dto.model.UserDto;
  import com.immutablesmapstruct.demo.dto.model.UserStatusDto;
  import org.mapstruct.Mapper;
  import org.mapstruct.factory.Mappers;
  
  @Mapper(componentModel = "spring")
  public interface UserMapper {
  
      UserMapper USER_MAPPER_INSTANCE = Mappers.getMapper(UserMapper.class);
  
      UserDto userDaoToDto(User user);
  
      //Problem here.
      User userDtoToDao(UserDto userDto);
  
      UserStatusDto userStatusDaoToDto(UserStatus userStatusDao);
      UserStatus userStatusDtoToDao(UserStatusDto userStatusDto);
  }
  
  </code></pre>
  
  <p>If I look at the concrete method generated by MapStruct for <code>userDtoToDao</code> I can clearly see that the setters are not being recognized.</p>
  
  <pre><code>package com.immutablesmapstruct.demo.dto.mapper;
  
  @Generated(
      value = "org.mapstruct.ap.MappingProcessor",
      date = "2019-04-28T02:29:03-0700",
      comments = "version: 1.3.0.Final, compiler: javac, environment: Java 1.8.0_191 (Oracle Corporation)"
  )
  @Component
  public class UserMapperImpl implements UserMapper {
  ...
  ...
      @Override
      public User userDtoToDao(UserDto userDto) {
          if ( userDto == null ) {
              return null;
          }
  
          com.immutablesmapstruct.demo.dao.model.User.Builder user = User.builder();
  
          return user.build();
      }
  ....
  ....
  }
  </code></pre>