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

orika Error "java.lang.IllegalArgumentException: 'request.params['cp']{}' is not a valid element property for Object" Map<String,List<String>> to Double #332

Closed rajcspsg closed 4 years ago

rajcspsg commented 4 years ago

I'm using orika to map value between different java beans.

Definition of ObjectA -

    public class ObjectA {

        private Request request;
    }

Definition of Request is -

    public class Request {

        private String id;

        private Map<String, List<String>> params;
    }

Definition of ObjectB -

    public class ObjectB {

        private Long reqId;

        private Double cp;

    }

I've omitted the setters and getters for brevity.

Below is the code that maps from objectA to ObjectB -

    Map<String,String> fieldMap = new HashMap<>();
    fieldMap.put("request.id","reqId");
    fieldMap.put("request.params['cp']{}", "cp");

    ObjectA a = new ObjectA();
    Request request = new Request();
    request.setId("123");
    a.setRequest(request);

    Map<String, List<String>> params = new HashMap<String, List<String>>();
    params.put("id", new ArrayList<String>(){{add("2");}});
    params.put("cp", new ArrayList<String>(){{add("0.51"); add("0.52"); add("0.53"); }});

    MappingContext.Factory mcf = new MappingContext.Factory();
    MapperFactory mapperFactory = new DefaultMapperFactory.Builder().mapNulls(false).mappingContextFactory(mcf).dumpStateOnException(false).build();
    ClassMapBuilder<ObjectA, ObjectB> impBuilder = mapperFactory.classMap(ObjectA.class, ObjectB.class);
    fieldMap.forEach((k,v) -> impBuilder.field(k,v));
    impBuilder.register();

    BoundMapperFacade<ObjectA, ObjectB> delegate = mapperFactory.getMapperFacade(ObjectA.class, ObjectB.class);

    ObjectB b = delegate.map(a);

The code is in github here.

When I run this program I'm getting below error -

Exception in thread "main" java.lang.IllegalArgumentException: 'request.params['cp']{}' is not a valid element property for ObjectA at ma.glasnost.orika.property.PropertyResolver.getElementProperty(PropertyResolver.java:566) at ma.glasnost.orika.property.PropertyResolver.getProperty(PropertyResolver.java:682) at ma.glasnost.orika.property.PropertyResolver.getProperty(PropertyResolver.java:638) at ma.glasnost.orika.metadata.ClassMapBuilder.resolveProperty(ClassMapBuilder.java:873) at ma.glasnost.orika.metadata.FieldMapBuilder.(FieldMapBuilder.java:78) at ma.glasnost.orika.metadata.FieldMapBuilder.(FieldMapBuilder.java:61) at ma.glasnost.orika.metadata.ClassMapBuilder.fieldMap(ClassMapBuilder.java:328) at ma.glasnost.orika.metadata.ClassMapBuilder.fieldMap(ClassMapBuilder.java:311) at ma.glasnost.orika.metadata.ClassMapBuilder.field(ClassMapBuilder.java:249) at mapper.ObjectAToObjectBDemo.lambda$main$0(ObjectAToObjectBDemo.java:36) at java.util.HashMap.forEach(HashMap.java:1289) at mapper.ObjectAToObjectBDemo.main(ObjectAToObjectBDemo.java:36)

I want to map first element of the key in "cp" in map params of the request object ObjectA to variable cp in ObjectB.

What is wrong with my mapping fieldMap.put("request.params['cp']{}", "cp"); and How can I fix the same?

Note: I'm using orika version 1.5.4.

I've asked the same question in stackoverflow here

stapetro commented 4 years ago

Hello, I fixed it with a few corrections:

...
// fix 1
fieldMap.put("request.params['cp'][0]", "cp"); // instead of request.params['cp']{} that gives you the last element
...
Map<String, List<String>> params = new HashMap<String, List<String>>();
...add params
// fix 2
request.setParams(params);

You can find the working fix here. I might delete the branch in future after you confirm the fix is working on your side.

rajcspsg commented 4 years ago

@stapetro your solution is working. I will close this issue.