Skip to content

#3949 Support SET_TO_NULL for overloaded target methods, requiring a cast#3988

Open
hduelme wants to merge 4 commits intomapstruct:mainfrom
hduelme:issue-3949
Open

#3949 Support SET_TO_NULL for overloaded target methods, requiring a cast#3988
hduelme wants to merge 4 commits intomapstruct:mainfrom
hduelme:issue-3949

Conversation

@hduelme
Copy link
Contributor

@hduelme hduelme commented Feb 1, 2026

Currently, invalid code is generated when SET_TO_NULL is used, as described in #3949.

This PR changes the generated code to include an explicit cast when more than two setters with the same name are present.

MapStruct does not fully support overloaded target methods yet (see #1135). To account for this limitation, the tests use a workaround: the preferred target type is determined via the getter with the same name to verify that the correct setter is invoked when passing null.

Copy link
Member

@filiphr filiphr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the PR @hduelme. I've left some comments. From the current state I am not sure that this would work for types with builder.

Comment on lines 919 to 921
public long settersWithName(String name) {
return getSetters().stream().filter( setter -> setter.getSimpleName().equals( name ) ).count();
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would not expose this in the Type. This check should be in the PropertyMapping. We can actually implement this a bit better and stop the iteration if the count reaches 2. No need to iterate through all setters.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moved to PropertyMapping and break if the second one is found.

Comment on lines 2277 to 2282
if (propertyMapping.getAssignment() instanceof SetterWrapper
&& ((SetterWrapper) propertyMapping.getAssignment()).isSetExplicitlyToNull()
&& ((SetterWrapper) propertyMapping.getAssignment()).isMustCastForNull()) {
// Setting to null with cast might require an import
types.add( propertyMapping.getTargetType() );
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not the responsibility of the BeanMappingMethod. The getImportTypes() of the SetterWrapper should do this instead. We should pass the targetType to the SetterWrapper, in a similar way like we are doing for the UpdateWrapper

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moved to SetterWrapper like you suggested

includeSourceNullCheck && nvpms == SET_TO_NULL && !targetType.isPrimitive(),
nvpms == SET_TO_DEFAULT );
nvpms == SET_TO_DEFAULT,
this.method.getResultType().settersWithName( this.targetWriteAccessor.getSimpleName() ) > 1
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We cannot implement this like this, because the method resultType is not what has the setters. If the resultType has a builder then the setters we are using are actually in the builder, not in the result type.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed to look at the enclosing class.

@hduelme
Copy link
Contributor Author

hduelme commented Feb 3, 2026

@filiphr as you suggested, I moved the import logic to the SetterWrapper.
Now the containing class of the targetWriteAccessor is checked if more than one method with the name is present.

In addition I added the tests where sub-mapping is generated.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants