Converting a nested collection using Dozer

二次信任 提交于 2020-01-14 12:56:10

问题


I have a class A which has a nested set of class B:

public class A {
    private Set<B> children;
}

public class B {
    private int value;
}

I also have a class C which has a nested set of class D:

public class C {
    private Set<D> children;
}

public class D {
    private int value;
}

Now given a List of A, how do I convert it to a List of C? Ideally I should not have to supply any mapping hints since I am using generics. For example:

List<A> src = new ArrayList<A>();
// ----- Add some A's to src -----
List<C> dst = mapper.map(src, List<C>.class);

Obviously, the syntax of last line is not correct. What should it be? Also how do I tell Dozer what type of a List or a Set to create?

Thanks.

Naresh


回答1:


This is actually answered in their FAQ, but it's all the way down in the advanced section for some reason. I don't think this is an advanced topic, I think it's a common thing to want to do. You do it with a collection hint.

When mapping collections, how do I tell Dozer what type of data objects I want in the destination collection?

Hints are supported to handle this use case. Hints are not required if you are using JDK 1.5 Generics because the types can be auto detected by Dozer. But if you are not using generics, to convert a Collection/Array to a Collection/Array with different type objects you can specify a Hint to let Dozer know what type of objects you want created in the destination list. If a Hint is not specified for the destination field, then the destination Collection will be populated with objects that are the same type as the elements in the src Collection.

<field>
  <a>someList</a>
  <b>otherList</b> 
  <b-hint>org.dozer.vo.TheFirstSubClassPrime</b-hint> 
</field>

That answer shows you how to do it in xml. Here's how you can do it in java code with a Mapping:

import org.dozer.loader.api.BeanMappingBuilder;

import static org.dozer.loader.api.FieldsMappingOptions.hintB;

public class Mapping extends BeanMappingBuilder {
    @Override
    protected void configure() {
        mapping(Subject.class, JsonSubject.class)
                .fields("names", "names", hintB(JsonName.class));
    }
}

The hint tells dozer, "this list of A's should be converted to a list JsonName instances". Here's how you add this mapping to your mapper:

    mapper = new DozerBeanMapper();
    mapper.addMapping(new Mapping());



回答2:


You should simply expand this list convertion. Dozer convert JavaBeans and such objects, not collections. So, if you want to pass collections, you can create a wrapper like

public class EntityConverter {
    private Mapper mapper;

    public EntityConverter(Mapper mapper) {
        this.mapper = mapper;
    }

    public <F, T> List<T> convert(List<F> fromList, final Class<T> toClass) {
        return Lists.transform(fromList, new Function<F, T>() {
            @Override
            public T apply(F from) {
                return convert(from, toClass);
            }
        });
    }

    public <F, T> T convert(F from, final Class<T> toClass) {
        if (from == null) return null;
        return mapper.map(from, toClass);
    }
}

Note: This code use Guava.



来源:https://stackoverflow.com/questions/9318488/converting-a-nested-collection-using-dozer

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!