Skip to content

Ambiguous presence check methods issue with optional @Context for @Condition #3993

@daberni

Description

@daberni

Expected behavior

I am having issues with an optional @Context parameter in combination with @Condition checks.

The specific Mapper declares 2 signatures of the same @Condition, one with @Context and one without @Context being optional. The calling side should decide itself, which signature to use.

  • Entity map(Model model) should use JsonNullableMapper.isPresent(JsonNullable<T> nullable)
  • void update(Model model, @MappingTarget Entity entity, @Context PropertyChangedTracker tracker) should use JsonNullableMapper.isPresent(JsonNullable<T> nullable, @Context PropertyChangedTracker tracker)

Actual behavior

error: Ambiguous presence check methods found for checking JsonNullable<OffsetDateTime>: boolean JsonNullableMapper.isPresent(JsonNullable<T> nullable, @Context PropertyChangedTracker tracker), boolean JsonNullableMapper.isPresent(JsonNullable<T> nullable). See https://mapstruct.org/faq/#ambiguous for more info.
	void update(Model model, @MappingTarget Entity entity, @Context PropertyChangedTracker tracker);

When I only specify the signature with @Context:

@Condition
boolean isPresent(JsonNullable<T> nullable, @Context PropertyChangedTracker tracker)

The @Condition is not used anywhere at all, where the @Context isn't specified on the root mapping method.

So for the void update(Model model, @MappingTarget Entity entity, @Context PropertyChangedTracker tracker) method, everything works as expected, but the Entity map(Model model) doesn't have any conditions at all.

Steps to reproduce the problem

@Mapper
public interface JsonNullableMapper {

	default <T> T map(JsonNullable<T> nullable) {
		return nullable.get();
	}

	@Condition
	default <T> boolean isPresent(JsonNullable<T> nullable) {
		return nullable.isPresent();
	}

	@Condition
	default <T> boolean isPresent(JsonNullable<T> nullable, @Context PropertyChangedTracker tracker) {
		boolean present = nullable.isPresent();
		if (tracker != null && present) {
			tracker.markChanged();
		}
		return present;
	}

}

The essence is, I want to keep track if any JsonNullable is ever isPresent() throughout the whole mapping hierarchy.

But the PropertyChangedTracker should be optional, depending on the general mapping context:

@Mapper(uses = JsonNullableMapper.class)
public interface EntityMapper {

    Entity map(Model model);

    void update(Model model, @MappingTarget Entity entity, @Context PropertyChangedTracker tracker);

}

class Model {

    private JsonNullable<String> name;

}

MapStruct Version

1.6.3

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions