Dozer deep mapping Set to Set

2019-05-06 21:39发布

问题:

Disclaimer: the same question has already been asked here Mapping deep properties with intermediate collections in dozer, but it has no accepted answer (and no proper answer for my case).

So the question. I have a realm composed by a ComplexObject like the following

public class ComplexObject {
  private Set<AnotherComplexObject> inner;
  ... //other fields, setters and getters
}
public Class AnotherComplexObject {
  private String property;
  ... //other fields, setters and getters
}

Now, I am mapping ComplexObject to Target, where Target has a Set<String> property.

public class Target {
  private Set<String> targetString;
  ... //other fields, setters and getters
}

I want to map each ComplexObject inner.property onto one Target targetString. Something that semantically looks like (this does not work of course, property is not a member of Set and Dozer generates a MappingException):

<mapping>
  <class-a>ComplexObject</class-a>
  <class-b>Target</class-b>
  <field>
    <a>inner.property</a>
    <b>targetString</b>
  </field>
</mapping>


I can accomplish my goal if I modify the toString method of AnotherComplexObject to

public class AnotherComplexObject {
  public String toString(){
    return property;
  }
}

Then, Dozer will detect the source Set is of "type" AnotherComplexObject while the target Set is of String and will use the method toString during the conversion. Unfortunately, this is not quite a solution since I will need a method in my POJO just to let Dozer doing the conversion.

What does work is to write a custom converter which overrides the convert method to check if source is a Set and then supposes the objects in the set are AnotherComplexObject and doing the conversion from this point on but somehow I feel this is not best nor the more elegant solution.
Any other idea about how to solve this problem?

回答1:

Maybe my answer can be useful for you:

I think, you can write such a mapping

<mapping>
  <class-a>Baz</class-a>
  <class-b>Target</class-b>
  <field>
    <a>foos</a>
    <b>fooStrings</b>
  </field>
</mapping>

<custom-converters> 
  <converter type="CustomFooConverter">
    <class-a>
      Foo
    </class-a>
    <class-b>
      String
    </class-b>
  </converter>
</custom-converters>

And implement CustomFooConverter to get string field of foo and return it as a String.

I think you can post a feature request to support mapping to primitives as

<mapping>
  <class-a>Foo</class-a>
  <class-b>String</class-b>
  <field>
    <a>string</a>
  </field>
</mapping>

into Dozer GitHub