4

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?

Community
  • 1
  • 1
ThanksForAllTheFish
  • 7,101
  • 5
  • 35
  • 54

1 Answers1

3

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

Community
  • 1
  • 1
Dmitry Spikhalskiy
  • 5,379
  • 1
  • 26
  • 40
  • @Dmitry, Actually, I am not using the XML-mapping provided by Dozer, but its API. I tried the mapping you propose but I was getting a MappingException. The API mapping I was using: `mapping(Baz.class, Target.class).fields(foos,foosString,FieldsMappingOptions.customConverter(CustomConverter))`. This has the same meaning of your xml, right? The exception: `Destination Type (java.util.Set) is not accepted by this Custom Converter (CustomConverter)`. The converter: `public class CustomConverter extends DozerConverter`. I guess I will obtain the same using the XML configuration – ThanksForAllTheFish Jan 09 '13 at 15:36
  • 1
    @mardavi No, your mapping are not correct. You set a custom converter for set fields, you can't do it, dozer automatically converts set to set. I set a custom converter from class Foo to class String, it is even another type of a converter. BTW, unfortunately as I know, you can not set a class level custom converter by code-based configuration, so you can't do as well as I do in xml config – Dmitry Spikhalskiy Jan 09 '13 at 17:14
  • @Dmitry, you are right! I ended up with that not-working configuration because I couldn't set a class-level converter using the APIs. Then in my previous comment I forgot such reason! Thanks! – ThanksForAllTheFish Jan 10 '13 at 09:21
  • @mardavi You are welcome. We will [try](https://github.com/DozerMapper/dozer/issues/58) to implement code-based class-level custom-converters configuration into the next 5.5.0 Dozer release. – Dmitry Spikhalskiy Jan 10 '13 at 10:31
  • @mardavi Please, mark my answer as a solution if it is helpful for you. – Dmitry Spikhalskiy Jan 11 '13 at 07:37