6

Suppose I have the following classes

public class Baz {
  private List<Foo> foos = new ArrayList<Foo>();
}

public class Foo {
  private String string;
}

public class Target {
  private List<String> fooStrings = new ArrayList<String>();
}

Is there any mapping I can use to, given a Baz, map it to the target class and get a list of the strings contained within the foo's in Baz? The following mapping does not work

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

Because string is not a property of foos (which is of type List). I would have thought Dozer would be clever enough to, if it encountered a collection in a deep mapping, and the target was also a collection, to be able to break the deep property name into two and iterate across the collection to get the child part of the deep mapping from the collection members. Apparently not. Is there a solution short of making a feature request of Dozer?

Jherico
  • 28,584
  • 8
  • 61
  • 87
  • How is my question a duplication of a question asked 3 years after mine? – Jherico Sep 22 '15 at 00:28
  • Possible duplicated by [Dozer deep mapping Set to Set](http://stackoverflow.com/questions/14212708/dozer-deep-mapping-setcomplexobject-to-setstring). @Jherico I am sorry for the confusion. Stackoverflow only allows to mark post as a duplicate if the other one contains an accepted answer. – rafalmag Sep 22 '15 at 11:45

3 Answers3

1

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

Dmitry Spikhalskiy
  • 5,379
  • 1
  • 26
  • 40
1

You could always write your own CustomConverter.

It makes sense why Dozer isn't able to handle this as you expect since at runtime it has no type information about the List foos and can't guarantee that every Object in the list is actually a Foo.

matt b
  • 138,234
  • 66
  • 282
  • 345
  • 1
    Its not dozer's job to ensure that every item in a List is actually a Foo. In fact it doesn't even have to care about that. All it needs to know that the member items of the list have a property 'string', and its up to me, the developer to ensure that's always the case. Writing a custom converters for an older version of Dozer is what I've been doing. i was hoping in the last 2 major version of Dozer someone would have addressed this fairly obvious (IMHO) use case. – Jherico Feb 04 '10 at 01:49
0

I think you can do it without custom converter.

Override the toString() method of Foo class like below:

@Override
public String toString(){
return this.getString(); //assuming string property has a getter method. if not,write this.string

And now the follwing mapping:

<mapping>
<class-a>fully qualified name of Baz(with package name)</class-a>
<class-b>same for Target</class-b>
<field>
   <a>foos</a>
   <b>fooStrings</b>
   <a-hint>foo</a-hint>
   <b-hint>java.lang.String</b-hint>
</field>
</mapping>
Priyank Doshi
  • 12,895
  • 18
  • 59
  • 82
  • 1
    That's a very non-general solution. It only allows you to select a single property per class *hierarchy* with which to do this, and kills the existing toString() functionality, which is typically pretty valuable for debugging. – Jherico Jul 02 '12 at 20:08