orika-mapper / orika

Simpler, better and faster Java bean mapping framework
http://orika-mapper.github.io/orika-docs/
Apache License 2.0
1.29k stars 269 forks source link

Compile error: no such field: java #322

Closed leeonky closed 5 years ago

leeonky commented 5 years ago

Got compile error when mapping data from int to Integer in List.

How to reproduce issue:

public class Issue322TestCase {

    @Test
    public void compile_error_when_customized_list_element_mapping_int_to_integer() {
        PersonList personList = new PersonList();
        Person person = new Person();
        person.age = 20;
        personList.persons.add(person);

        MapperFactory mapperFactory = MappingUtil.getMapperFactory();
        mapperFactory.classMap(PersonList.class, PersonAgeListDto.class)
                .field("persons{age}", "personAges{}")
                .byDefault()
                .register();

        PersonAgeListDto dest = mapperFactory.getMapperFacade().map(personList, PersonAgeListDto.class);

        assertEquals(1, dest.personAges.size());
        assertEquals(Integer.valueOf(20), dest.personAges.get(0));
    }

    public static class Person {
        public int age;
    }

    public static class PersonList {
        public List<Person> persons = new ArrayList<>();
    }

    public static class PersonAgeListDto {
        public List<Integer> personAges;
    }
}

Exception during mapping:

Caused by: compile error: no such field: java
    at javassist.compiler.MemberResolver.lookupField(MemberResolver.java:321)
    at javassist.compiler.MemberResolver.lookupFieldByJvmName(MemberResolver.java:307)
    at javassist.compiler.TypeChecker.fieldAccess(TypeChecker.java:904)
    at javassist.compiler.TypeChecker.atFieldRead(TypeChecker.java:831)
    at javassist.compiler.TypeChecker.atExpr(TypeChecker.java:605)
    at javassist.compiler.ast.Expr.accept(Expr.java:71)
    at javassist.compiler.TypeChecker.fieldAccess(TypeChecker.java:888)
    at javassist.compiler.TypeChecker.atFieldRead(TypeChecker.java:831)
    at javassist.compiler.TypeChecker.atExpr(TypeChecker.java:605)
    at javassist.compiler.ast.Expr.accept(Expr.java:71)
    at javassist.compiler.TypeChecker.atCallExpr(TypeChecker.java:693)

Generated mapping code:

package ma.glasnost.orika.examples;

public class Orika_PersonAgeListDto_PersonList_Mapper96810527667653$0 extends ma.glasnost.orika.impl.GeneratedMapperBase {

    @Override
    public void mapAtoB(java.lang.Object a, java.lang.Object b, ma.glasnost.orika.MappingContext mappingContext) {

        super.mapAtoB(a, b, mappingContext);

// sourceType: PersonList
        ma.glasnost.orika.examples.TestCase.PersonList source = ((ma.glasnost.orika.examples.TestCase.PersonList) a);
// destinationType: PersonAgeListDto
        ma.glasnost.orika.examples.TestCase.PersonAgeListDto destination = ((ma.glasnost.orika.examples.TestCase.PersonAgeListDto) b);

        java.util.List new_destinationPersonAges0 = null;
        if (!(((java.util.List) source.persons) == null)) {
            new_destinationPersonAges0 = ((java.util.List) new java.util.ArrayList());
        } else {
            new_destinationPersonAges0 = null;
        }
        java.lang.Integer personAges_destination0Element = null;
        boolean personAges_destination0ElementShouldBeAddedToCollector = false;
        if (!(((java.util.List) source.persons) == null)) {

            java.util.Iterator persons_$_iter = ((java.util.List) source.persons).iterator();
            while (persons_$_iter.hasNext()) {
                ma.glasnost.orika.examples.TestCase.Person persons_source0Element = ((ma.glasnost.orika.examples.TestCase.Person) persons_$_iter.next());
                personAges_destination0ElementShouldBeAddedToCollector = true;
                mappingContext.beginMapping(((ma.glasnost.orika.metadata.Type) usedTypes[0]), ((java.util.List) source.persons), ((ma.glasnost.orika.metadata.Type) usedTypes[1]), new_destinationPersonAges0);
                try {

                    personAges_destination0Element = java.lang.Integer.valueOf(((int) persons_source0Element.age));
                    if (personAges_destination0ElementShouldBeAddedToCollector) {
                        new_destinationPersonAges0.add(((java.lang.Integer) personAges_destination0Element));
                        personAges_destination0ElementShouldBeAddedToCollector = false;
                        personAges_destination0Element = null;
                    }
                } finally {
                    mappingContext.endMapping();
                }

            }
        }

        if (!(new_destinationPersonAges0 == null) && !new_destinationPersonAges0.isEmpty()) {
            if (((java.util.List) destination.personAges) == null) {
                destination.personAges = ((java.util.List) new java.util.ArrayList());
            } else {

                ((java.util.List) destination.personAges).clear();
            }

            ((java.util.List) destination.personAges).addAll(new_destinationPersonAges0);
        }

        if (customMapper != null) {
            customMapper.mapAtoB(source, destination, mappingContext);
        }
    }

    @Override
    public void mapBtoA(java.lang.Object a, java.lang.Object b, ma.glasnost.orika.MappingContext mappingContext) {

        super.mapBtoA(a, b, mappingContext);

// sourceType: PersonAgeListDto
        ma.glasnost.orika.examples.TestCase.PersonAgeListDto source = ((ma.glasnost.orika.examples.TestCase.PersonAgeListDto) a);
// destinationType: PersonList
        ma.glasnost.orika.examples.TestCase.PersonList destination = ((ma.glasnost.orika.examples.TestCase.PersonList) b);

        java.util.List new_destinationPersons0 = null;
        if (!(((java.util.List) source.personAges) == null)) {
            new_destinationPersons0 = ((java.util.List) new java.util.ArrayList());
        } else {
            new_destinationPersons0 = null;
        }
        ma.glasnost.orika.examples.TestCase.Person persons_destination0Element = null;
        boolean persons_destination0ElementShouldBeAddedToCollector = false;
        if (!(((java.util.List) source.personAges) == null)) {

            java.util.Iterator personAges_$_iter = ((java.util.List) source.personAges).iterator();
            while (personAges_$_iter.hasNext()) {
                java.lang.Integer personAges_source0Element = ((java.lang.Integer) personAges_$_iter.next());
                if (persons_destination0Element == null || !(((((java.lang.Integer) personAges_source0Element) != null && ((int) persons_destination0Element.age) == ((java.lang.Integer) personAges_source0Element).java.lang.IntegerValue())))) {

                    persons_destination0Element = ((ma.glasnost.orika.examples.TestCase.Person) ((ma.glasnost.orika.BoundMapperFacade) usedMapperFacades[0]).newObject(personAges_source0Element, mappingContext));
                    persons_destination0ElementShouldBeAddedToCollector = true;
                }
                mappingContext.beginMapping(((ma.glasnost.orika.metadata.Type) usedTypes[1]), ((java.util.List) source.personAges), ((ma.glasnost.orika.metadata.Type) usedTypes[0]), new_destinationPersons0);
                try {

                    if ((persons_destination0Element == null)) {

                        persons_destination0Element = ((ma.glasnost.orika.examples.TestCase.Person) ((ma.glasnost.orika.BoundMapperFacade) usedMapperFacades[0]).newObject(personAges_source0Element, mappingContext));
                    }
                    if (!(((java.lang.Integer) personAges_source0Element) == null)) {
                        persons_destination0Element.age = ((java.lang.Integer) personAges_source0Element).intValue();
                    }
                    if (persons_destination0ElementShouldBeAddedToCollector) {
                        new_destinationPersons0.add(((ma.glasnost.orika.examples.TestCase.Person) persons_destination0Element));
                        persons_destination0ElementShouldBeAddedToCollector = false;
                    }
                } finally {
                    mappingContext.endMapping();
                }

            }
        }

        if (!(new_destinationPersons0 == null) && !new_destinationPersons0.isEmpty()) {
            if (((java.util.List) destination.persons) == null) {
                destination.persons = ((java.util.List) new java.util.ArrayList());
            } else {

                ((java.util.List) destination.persons).clear();
            }

            ((java.util.List) destination.persons).addAll(new_destinationPersons0);
        }

        if (customMapper != null) {
            customMapper.mapBtoA(source, destination, mappingContext);
        }
    }

Incorrect line:

if (persons_destination0Element == null || !(((((java.lang.Integer) personAges_source0Element) != null && ((int) persons_destination0Element.age) == ((java.lang.Integer) personAges_source0Element).java.lang.IntegerValue())))) {

Maybe the solution is:

--- a/core/src/main/java/ma/glasnost/orika/impl/generator/specification/Convert.java
+++ b/core/src/main/java/ma/glasnost/orika/impl/generator/specification/Convert.java
@@ -54,7 +54,7 @@ public class Convert extends AbstractSpecification {
             if (destination.type().isPrimitive() && source.type().isPrimitive()) {
                 return format("(%s == %s)", destination, source);
             } else if (destination.type().isPrimitive()) {
-                return format("(%s != null && %s == %s.%sValue())", source, destination, source, source.type().getName());
+                return format("(%s != null && %s == %s.%sValue())", source, destination, source, destination.type().getName());
             } else if (source.type().isPrimitive()) {
                 return format("(%s != null && %s.%sValue() == %s)", destination, destination, destination.type()
                         .getPrimitiveType()