modelmapper: ModelMapper mapper.skip() doesn't work for pojo objects with circular dependency

I have two pojo objects: Husband, Wife which reference each other.

Husband.java

public class Husband {
   private String name;
   private int age;
   private String man;
   private Wife wife;

   // getter, setter, builder, constructor are removed for berevity
}

Wife.java

public class Wife {
   private String name;
   private int age;
   private String woman;
   private Husband husband;

   // getter, setter, builder, constructor are removed for berevity
}

I’ve created simple typeMap rulings for both objects, where the referenced object is skipped.

My test class:

public class ModelTest {

@Test
public void test() {
    ModelMapper modelMapper = new ModelMapper();
    TypeMap<Wife, Wife> typeWife = modelMapper.createTypeMap(Wife.class, Wife.class);
    typeWife.addMappings(mapper -> {
        mapper.skip(Wife::setHusband);
    });

    TypeMap<Husband, Husband> typeHusband = modelMapper.createTypeMap(Husband.class, Husband.class);
    typeHusband.addMappings(mapper -> {
        mapper.skip(Husband::setWife);
    });

    Wife wife = Wife.builder().age(25).name("Sarah").woman("good woman").build();
    Husband husband = Husband.builder().age(28).name("Imtiaz").man("good man").build();
    wife.setHusband(husband);
    husband.setWife(wife);

    Husband updatedHusband = Husband.builder().age(28).name("Imtiaz Shakil").man("slightly good man").build();
    modelMapper.map(updatedHusband, husband);
    System.out.println(husband.toString());
    System.out.println(husband.getWife().toString());
    }

}

When mapping updatedHusband to husband, setWife() method is not skipped. But, if I remove typeWife mapping from modelMapper the code works fine.

I’m using ModelMapper 1.1.3

Thanks.

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Comments: 16 (9 by maintainers)

Commits related to this issue

Most upvoted comments

Please take a look #337 and GH336.java#L100-L119 that I want to write a test to reproduce your issue with old way.

when creating typeHusband map, we first apply current mapping rules before performing implicit mapping.

That’s what my solution want to solve. Currently, modelmapper don’t have any approach to do this.

hi @imtiazShakil ,

Can you try our new api?

ModelMapper modelMapper = new ModelMapper();
modelMapper.getConfiguration().setImplicitMappingEnabled(false);
modelMapper.typeMap(Husband.class, Husband.class)
    .addMappings(husbandPropertyMap)
    .implicitMappings();
modelMapper.typeMap(Wife.class, Wife.class)
    .addMappings(wifePropertyMap)
    .implicitMappings();

hi @imtiazShakil , I’m working on the implementation. I can reproduce that the TypeMap will be weird after unexpected implicit mapping. But I’m not sure what actual the issue is (I’m not challenging it’s not a bug, I just want to write an unit test to reproduce the issue). Is that your problem is that: the husband of wife or the wife of husband will be null after mapping?

Thanks.

I think it’s annoying that implicit mapping(auto property mapping) do what we don’t want it do, but we also need implicit mapping for convenience.

I think it’s ordering problem that there will be less issue if the implicit mapping is invoked AFTER our manual mappings. For your example, the implicit mappings are created when you create type map, so it’s no use to skip the wife after that.

I will try to create an api that you can perform implicit mapping after manually mapping. WDYT?