Orika - отображение объекта в список (отображение один ко многим)

У меня есть следующие два класса

class A {
    class InnerA {
        private String field;

        // getters/setters
    }

    private Collection<InnerA> collection;

    // getters/setters
}

class B {
    private String field;

    // getters/setters
}

Можно ли сопоставить A с коллекцией B (A.collection.field следует сопоставить с коллекцией B.field)?

Я пытался использовать собственный конвертер, но мне нужно только управлять java.lang.VerifyError:

    mapperFactory.getConverterFactory().registerConverter(new CustomConverter<A, Collection<B>>() {

        @Override
        public Collection<B> convert(
                A arg0, Type<? extends Collection<B>> arg1) {

            Collection<B> result = new ArrayList<B>();

            Iterator<Item> it = arg0.getCollection().iterator();
            while(it.hasNext()){
                it.next();
                result.add(new B());
            }

            return result;
        }

    });

приводит к:

java.lang.VerifyError: Inconsistent args count operand in invokeinterface in method    ma.glasnost.orika.generated.Orika_ArrayList_A_Mapper845657274.mapAtoB(Ljava/lang/Object;Ljava/lang/Object;Lma/glasnost/orika/MappingContext;)V at offset 74  
at java.lang.Class.getDeclaredConstructors0(Native Method)  
at java.lang.Class.privateGetDeclaredConstructors(Class.java:2404)  
at java.lang.Class.getConstructor0(Class.java:2714)     
at java.lang.Class.newInstance0(Class.java:343)     
at java.lang.Class.newInstance(Class.java:325)  

person lbednaszynski    schedule 12.03.2013    source источник
comment
у вас есть несколько версий orika в пути к классам?   -  person drone.ah    schedule 12.03.2013
comment
нет, проверил зависимость: дерево через maven. Orika 1.4.0 и Javassist 3.17.1-GA.   -  person lbednaszynski    schedule 12.03.2013
comment
Первое замечание: если вы хотите, чтобы Orika имела доступ к вашему InnerA, InnerA должен быть общедоступным и статическим.   -  person Sidi    schedule 13.03.2013


Ответы (1)


Конечно, вы можете отобразить его, вам нужно просто сделать InnerA общедоступным:

List<B> dest = mapper.mapAsList(sourceA.getCollection(), B.class);

Если InnerA не является общедоступным, Orika не может использовать его

MapperFacade mapper = new ConfigurableMapper() {
    @Override
    protected void configure(MapperFactory factory) {
    factory.registerMapper(new CustomMapper<A, Collection<B>>() {
        @Override
        public void mapAtoB(A a, Collection<B> b, MappingContext context) {                     b.addAll(mapperFacade.mapAsList(a.collection, B.class));

            for(B item : b) {
                item.propertyA = a.propertyA;
            }
        }               
    });             
    factory.registerConcreteType(Collection.class, ArrayList.class);
        }           
};  
final Type<Collection<B>> collectionOfB = new TypeBuilder<Collection<B>>() {}.build();
Collection<B> dest = mapper.map(source, TypeFactory.valueOf(A.class), collectionOfB);           
person Sidi    schedule 13.03.2013
comment
да, этот ответ полезен, но что, если я хочу добавить свойство из A в каждое B? то есть свойство A.propertyA в каждом B.property? - person lbednaszynski; 20.03.2013
comment
Это не может быть обработано автоматическим сопоставлением Orika, но вы можете создать собственный Mapper‹A, Collection‹B›› реализовать его и зарегистрироваться в MapperFactory и использовать автоматическое сопоставление для mapper.mapAsList(sourceA.getCollection(), B.class) ; // для InnerA ‹-> B вы используете обычную Java для установки свойства из A в каждый экземпляр B - person Sidi; 21.03.2013