Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mapping creates instances for null objects #32

Closed
mlindenmuth opened this issue Jan 2, 2013 · 6 comments
Closed

Mapping creates instances for null objects #32

mlindenmuth opened this issue Jan 2, 2013 · 6 comments

Comments

@mlindenmuth
Copy link

If both source and destination have a matching property that is a complex object, when the property on source is null mapping causes the property on the destination to be created by the default constructor.

public class Source
{
    private SourceProperty property;

    ...
}

public class Destination
{
    private DestinationProperty property;

    ...
}

// source.getProperty() is null
Source source = new Source ();

// this results in destination.getProperty() not null
Destination destination = mapper.map(source, Destination.class);
@jhalterman
Copy link
Member

Thanks for reporting. This is a known issue (issue #6). I'll try to address it in the next release.

I'm curious, is this causing any difficulties for you?

@mlindenmuth
Copy link
Author

Oh, sorry, somehow missed that issue. Yes, it is a blocker for us since we expect null values in our object graph in some cases. Looping through the whole tree seems to defeat the point of being able to map objects automatically!

I've already sub-classed ModelMapper to check for a null root value (which i think may be fixed if this issue is fixed) but I didn't see any easy way to solve the above.

@Override
public <D> D map(Object source, Class<D> destinationType)
{
    if (source == null)
        return null;

    return super.map(source, destinationType);
}

@jhalterman
Copy link
Member

No worries. I was waiting to see if this issue would be a priority for anyone. Since it is, I'll make it a priority for myself, hopefully within the next day or two.

@mlindenmuth
Copy link
Author

I was wondering if there was a way to also add a generic root level converter. This was my first stab at solving the problem without any code changes but I thought it might be a helpful feature if it could catch objects at all levels of mapping:

Converter<Object, Object> nullCheck = new AbstractConverter<Object, Object>() 
{
    protected Object convert (Object source)
    {
        if (source != null)
        {
            // return something else
        }

        return null;
    }
};

@jhalterman
Copy link
Member

Two solutions I can see right now. The first is to set a property condition on your type map:

    modelMapper.createTypeMap(Source.class, Dest.class)
        .setPropertyCondition(Conditions.isNotNull());

This condition will be applied to all of the properties in the TypeMap (for a source and destination type), essentially, ensuring that nothing will be mapped for any source values that are null.

The second option is similar to what you were thinking with a global converter, which we don't support right now (since ModelMapper basically is the global converter). There is a notion of a global Provider though. A provider provides destination instances prior to their values being populated. You could try what you were thinking with a global provider set via: modelMapper.getConfiguration().setProvider.

I still intend to look into the problem of instantiating intermediate objects on the destination when mapping a source value that is null.

@jhalterman jhalterman reopened this Jan 5, 2013
@jhalterman
Copy link
Member

Fixed via 3107b8c

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

No branches or pull requests

2 participants