mapstruct / mapstruct/mapstruct
Determine the builder class for a FreeBuilder type without the need of a static method in the type
Nobody has claimed this yet.
- Dominant language
- Java
- Stars
- 7.7k
- Forks
- 1.1k
- PR merge metrics
- No merged PRs in 30d
Description
Expected behavior
When I use a FreeBuilder interface/abstract class as a target of a mapper, I expect mapstruct to use the builder to construct the instance of that interface/abstract class.
Actual behavior
At compilation, I get the message
Ambiguous factory methods found for creating Target: Target Builder.build(), Target Builder.buildPartial(). See https://mapstruct.org/faq/#ambiguous for more info.
even though I use @Builder to specify the build method in @Mapper or in @BeanMapping.
Steps to reproduce the problem
I define my source and target class
public class Source {
private String value1;
private int value2;
public String getValue1() {
return value1;
}
public void setValue1(String value1) {
this.value1 = value1;
}
public int getValue2() {
return value2;
}
public void setValue2(int value2) {
this.value2 = value2;
}
}
@FreeBuilder
public interface Target {
String getValue1();
int getValue2();
class Builder extends Target_Builder {
}
}
and the mapper
import org.mapstruct.Mapper;
//@Mapper(uses = Target.Builder.class, builder = @Builder(buildMethod = "buildPartial"))
//@Mapper(uses = Target.Builder.class, builder = @Builder(buildMethod = "build"))
//@Mapper(uses = Target.Builder.class, builder = @Builder)
@Mapper(uses = Target.Builder.class)
public interface ExampleMapper {
// @BeanMapping(builder = @Builder(buildMethod = "buildPartial"))
// @BeanMapping(builder = @Builder(buildMethod = "build"))
// @BeanMapping(builder = @Builder)
Target apply(Source source);
}
with POM containing
<properties>
<freebuilder.version>2.8.0</freebuilder.version>
<mapstruct.version>1.5.5.Final</mapstruct.version>
</properties>
<dependencies>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct</artifactId>
<version>${mapstruct.version}</version>
</dependency>
<dependency>
<groupId>org.inferred</groupId>
<artifactId>freebuilder</artifactId>
<version>${freebuilder.version}</version>
<optional>true</optional>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<annotationProcessorPaths>
<path>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>${mapstruct.version}</version>
</path>
<path>
<groupId>org.inferred</groupId>
<artifactId>freebuilder</artifactId>
<version>${freebuilder.version}</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
</plugins>
</build>
Then run maven compile.
I attached a minimal project:
mapstruct-freebuilder.zip
MapStruct Version
MapStruct 1.5.5.Final
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the attached minimal project, the ExampleMapper, Target.Builder, and the @Builder configuration, then run Maven compile to reproduce the ambiguous factory-method error. Trace how the annotation processor discovers builders for the FreeBuilder Target interface. Done means a mapper can select the configured build or buildPartial method without requiring a static method on the target type.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- java
- Domain
- devtools
- Issue type
- Feature
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100