Skip to content

Determine the builder class for a FreeBuilder type without the need of a static method in the type #3314

@lionel-bartel

Description

@lionel-bartel

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

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions