Coder Social home page Coder Social logo

orika-mapper / orika Goto Github PK

View Code? Open in Web Editor NEW

This project forked from elaatifi/orika

1.3K 76.0 258.0 4.47 MB

Simpler, better and faster Java bean mapping framework

Home Page: http://orika-mapper.github.io/orika-docs/

License: Apache License 2.0

Java 100.00%
java mapper

orika's Introduction

Build Status Join the chat at https://gitter.im/orika-mapper GitHub site Maven Central Javadocs License: Apache 2.0

Orika !

NEW We are pleased to announce the release of Orika 1.5.4 ! This version is available on Maven central repository

What?

Orika is a Java Bean mapping framework that recursively copies (among other capabilities) data from one object to another. It can be very useful when developing multi-layered applications.

Why?

Struggling with hand coded and reflection-based mappers? Orika can be used to simplify the process of mapping between one object layer and another.

Our ambition is to build a comprehensive, efficient and robust Java bean mapping solution. Orika focuses on automating as much as possible, while providing customization through configuration and extension where needed.

Orika enables the developer to :

  • Map complex and deeply structured objects
  • "Flatten" or "Expand" objects by mapping nested properties to top-level properties, and vice versa
  • Create mappers on-the-fly, and apply customizations to control some or all of the mapping
  • Create converters for complete control over the mapping of a specific set of objects anywhere in the object graph--by type, or even by specific property name
  • Handle proxies or enhanced objects (like those of Hibernate, or the various mock frameworks)
  • Apply bi-directional mapping with one configuration
  • Map to instances of an appropriate concrete class for a target abstract class or interface
  • Map POJO properties to Lists, Arrays, and Maps

How?

Orika uses byte code generation to create fast mappers with minimal overhead.

Want to give Orika a try? Check out our new User Guide

Acknowledgements

  • YourKit supports Orika with its full-featured Java Profiler. Take a look at YourKit's leading software products: YourKit Java Profiler.

  • JetBrains kindly provides Orika with a free open-source licence for their IntelliJ IDEA Ultimate edition.

orika's People

Contributors

123haynes avatar agliznetsov avatar brabenetz avatar cesarsotovalero avatar cyrilcombe avatar eduarddrenth avatar elaatifi avatar flowenol avatar ikozar avatar jad7 avatar jmlmontero avatar kasramp avatar kirviq avatar leeonky avatar leonard84 avatar matt-deboer avatar muminc avatar ndr-brt avatar papegaaij avatar porunov avatar roadrunner2 avatar romanluo1990 avatar snyk-bot avatar srjturner avatar stapetro avatar tomashanley-toast avatar tsachev avatar wjam avatar yupengj avatar zeko868 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

orika's Issues

ClassNotFoundException: ma.glasnost.orika.impl.GeneratedMapperBase on remote jetty server

I have a Spring Boot application which uses websockets and Orika. I'm using war packaging (instead of jar) and spring-boot-maven-plugin generates 2 versions by default:

  • myproject.war - executable war package which consist jetty server, I'm able to run it with java -jar myproject.war;
  • myproject.war.original - war package without embedded jetty server which I use to deploy to remote jetty server.

First version of war works fine! And I haven't got any problems with it. But on remote jetty server I have an exception in my websocket controller:

ma.glasnost.orika.MappingException: ma.glasnost.orika.impl.generator.CompilerStrategy$SourceCodeGenerationException: Error compiling ma.glasnost.orika.generated.Orika_MessageEntity_MessageRequestDto_Mapper4074936221257$2
    at ma.glasnost.orika.impl.generator.MapperGenerator.build(MapperGenerator.java:105)
    at ma.glasnost.orika.impl.DefaultMapperFactory.buildMapper(DefaultMapperFactory.java:1360)
    at ma.glasnost.orika.impl.DefaultMapperFactory.lookupMapper(DefaultMapperFactory.java:757)
    at ma.glasnost.orika.impl.DefaultMapperFactory.lookupMapper(DefaultMapperFactory.java:707)
    at ma.glasnost.orika.impl.MapperFacadeImpl.resolveMapper(MapperFacadeImpl.java:584)
    at ma.glasnost.orika.impl.MapperFacadeImpl.resolveMappingStrategy(MapperFacadeImpl.java:216)
    at ma.glasnost.orika.impl.MapperFacadeImpl.map(MapperFacadeImpl.java:734)
    at ma.glasnost.orika.impl.MapperFacadeImpl.map(MapperFacadeImpl.java:714)
    at myproject.controller.websocket.chat.ChatController.sending(ChatController.java:40)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at org.springframework.messaging.handler.invocation.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:185)
    at org.springframework.messaging.handler.invocation.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:104)
    at org.springframework.messaging.handler.invocation.AbstractMethodMessageHandler.handleMatch(AbstractMethodMessageHandler.java:447)
    at org.springframework.messaging.simp.annotation.support.SimpAnnotationMethodMessageHandler.handleMatch(SimpAnnotationMethodMessageHandler.java:443)
    at org.springframework.messaging.simp.annotation.support.SimpAnnotationMethodMessageHandler.handleMatch(SimpAnnotationMethodMessageHandler.java:82)
    at org.springframework.messaging.handler.invocation.AbstractMethodMessageHandler.handleMessageInternal(AbstractMethodMessageHandler.java:408)
    at org.springframework.messaging.handler.invocation.AbstractMethodMessageHandler.handleMessage(AbstractMethodMessageHandler.java:346)
    at org.springframework.messaging.support.ExecutorSubscribableChannel$SendTask.run(ExecutorSubscribableChannel.java:135)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)
Caused by: ma.glasnost.orika.impl.generator.CompilerStrategy$SourceCodeGenerationException: Error compiling ma.glasnost.orika.generated.Orika_MessageEntity_MessageRequestDto_Mapper4074936221257$2
    at ma.glasnost.orika.impl.generator.JavassistCompilerStrategy.compileClass(JavassistCompilerStrategy.java:266)
    at ma.glasnost.orika.impl.generator.SourceCodeContext.compileClass(SourceCodeContext.java:249)
    at ma.glasnost.orika.impl.generator.SourceCodeContext.getInstance(SourceCodeContext.java:266)
    at ma.glasnost.orika.impl.generator.MapperGenerator.build(MapperGenerator.java:75)
    ... 23 common frames omitted
Caused by: javassist.CannotCompileException: by java.lang.NoClassDefFoundError: ma/glasnost/orika/impl/GeneratedMapperBase
    at javassist.ClassPool.toClass(ClassPool.java:1120)
    at javassist.ClassPool.toClass(ClassPool.java:1063)
    at javassist.ClassPool.toClass(ClassPool.java:1021)
    at javassist.CtClass.toClass(CtClass.java:1259)
    at ma.glasnost.orika.impl.generator.JavassistCompilerStrategy.compileClass(JavassistCompilerStrategy.java:259)
    ... 26 common frames omitted
Caused by: java.lang.NoClassDefFoundError: ma/glasnost/orika/impl/GeneratedMapperBase
    at java.lang.ClassLoader.defineClass1(Native Method)
    at java.lang.ClassLoader.defineClass(ClassLoader.java:760)
    at java.lang.ClassLoader.defineClass(ClassLoader.java:642)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at javassist.ClassPool.toClass2(ClassPool.java:1133)
    at javassist.ClassPool.toClass(ClassPool.java:1114)
    ... 30 common frames omitted
Caused by: java.lang.ClassNotFoundException: ma.glasnost.orika.impl.GeneratedMapperBase
    at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
    ... 39 common frames omitted

The exception is caused in a class:

@Controller
public class ChatController {

    @Autowired
    private MapperFacade mapper;

    ...

    @MessageMapping("/chat/{roomId}")
    public void sending(MessageRequestDto messageRequestDto, @DestinationVariable("roomId") long roomId, Authentication authentication) throws Exception {
        MessageEntity messageEntity = mapper.map(messageRequestDto, MessageEntity.class);
        ...
    }

Another strange, that it works fine in all my @RestControllers, for example:

@RestController
@RequestMapping(value = "/api/rooms",
        consumes = MediaType.APPLICATION_JSON_VALUE,
        produces = MediaType.APPLICATION_JSON_VALUE)
public class RoomController {

    @Autowired
    private IRoomService roomService;

    @Autowired
    private IMessageService messageService;

    @Autowired
    private MapperFacade mapper;

    @RequestMapping(value = "/{roomId}/messages", method = RequestMethod.GET)
    public List<MessageResponseDto> getRoomMessages(@PathVariable long roomId,
            @RequestParam(value = "offset", defaultValue = "0") int offset,
            @RequestParam(value = "limit", defaultValue = Constants.LIMIT) int limit) {
        ...
        List<MessageEntity> messages = messageService.findMessagesByRoomId(roomId, offset, limit);
        return mapper.mapAsList(messages, MessageResponseDto.class);
    }

MessageResponseDto extends MessageRequestDto

My Orika config:

@Component
public class MapperFacadeFactory implements FactoryBean<MapperFacade> {

    @Override
    public MapperFacade getObject() throws Exception {
        final MapperFactory mapperFactory = new DefaultMapperFactory.Builder().build();
        mapperFactory.getConverterFactory().registerConverter(new LocalDateTimeConverterToLocalDateTimeConverter());
        mapperFactory.classMap(MessageEntity.class, MessageResponseDto.class)
                     .fieldAToB("user.fullName", "userName")
                     .byDefault()
                     .register();

        return mapperFactory.getMapperFacade();
    }

    @Override
    public Class<?> getObjectType() {
        return MapperFacade.class;
    }

    @Override
    public boolean isSingleton() {
        return true;
    }
}

Remote and embedded jetty servers have the same version number: jetty-9.2.9.v20150224
Java version:

java version "1.8.0_40"
Java(TM) SE Runtime Environment (build 1.8.0_40-b25)
Java HotSpot(TM) 64-Bit Server VM (build 25.40-b25, mixed mode)

Orika version: 1.4.5
Spring Boot version: 1.2.3-RELEASE

Mapping gets called recursively

I have a simple mapping that is being called 3 times for each element in an array.

Here's my example:

mapperFacotry.classMap(TestDb.class, Test.class)
       .mapNulls(true)
       .field("name", "name")
       .field("getterMethodReturningList", "addresses")  //This gets called 3x for each element

In my TestDB.class I have the getterMethodReturningList as follows:

List<String> towns= new ArrayList<>();
for(Address a : this.getTests.getAllAddresses){
      towns.add(a.getTownName());
}
return towns

I am not sure why this is happening, but so far I have been unable to figure out how to find a work around.

Converting 2 objects with inheritance toward same destination

Hello,

(First thx for the great lib ๐Ÿ‘ )

I have the following situation, one class of type Parent, and a class of type Son. Son inherits from Parent. Son class has one more field that Parent.

Parent
^
|
Son

I want to convert both classes are into the same destination class of type Destination.

Parent -> Destination
Son -> Destination

Destination has 2 constructors, each one corresponding to the exact fields of Parent and Son.

I would like to use one constructor when converting Parent -> Destination
and the other one when Son -> Destination.

Unfortunatly this is not possible, once I have converted one instance of Parent -> Destination if I want to convert one instance of Son -> Destination it will use the same constructor.

This is because of the followng method inside the DefaultMapperFactory, it looks for the parent type checkSourceType.getSuperType(). This will return the object factory that was used for the Parent object.

@SuppressWarnings("unchecked")
protected <T, S> ObjectFactory<T> lookupExistingObjectFactory(final Type<T> destinationType, final Type<S> sourceType,
        final MappingContext context) {

    if (destinationType == null || sourceType == null) {
        return null;
    }
    ObjectFactory<T> result;
    Type<T> targetType = destinationType;

    ConcurrentHashMap<Type<? extends Object>, ObjectFactory<? extends Object>> localCache = objectFactoryRegistry.get(targetType);
    if (localCache == null) {
        localCache = new ConcurrentHashMap<Type<? extends Object>, ObjectFactory<? extends Object>>();
        ConcurrentHashMap<Type<? extends Object>, ObjectFactory<? extends Object>> existing = objectFactoryRegistry.putIfAbsent(
                targetType, localCache);
        if (existing != null) {
            localCache = existing;
        }
        result = null;
    } else {
        Type<?> checkSourceType = sourceType;
        do {
            result = (ObjectFactory<T>) localCache.get(checkSourceType);
            checkSourceType = checkSourceType.getSuperType();
        } while (result == null && !TypeFactory.TYPE_OF_OBJECT.equals(checkSourceType));
        if (result == null) {
            result = (ObjectFactory<T>) localCache.get(TypeFactory.TYPE_OF_OBJECT);
        }
    }
    return result;
}

So now I though that I could use the classMap.constructorB(......) method to specify manually the right constructor to use but the following method does not work either because the lookup is only done on the destination class. So when I arrive with my Son -> Destination, it will return the constructor specified for the Parent -> Destination

@SuppressWarnings({ "unchecked" })
private <S, D> void buildObjectFactories(ClassMap<S, D> classMap, MappingContext context) {
    Type<?> aType = classMap.getAType();
    Type<?> bType = classMap.getBType();

    if (classMap.getConstructorA() != null && lookupExistingObjectFactory(aType, TypeFactory.TYPE_OF_OBJECT, context) == null) {
        GeneratedObjectFactory objectFactory = objectFactoryGenerator.build(aType, bType, context);
        registerObjectFactory(objectFactory, (Type<Object>) aType);
    }

    if (classMap.getConstructorB() != null && lookupExistingObjectFactory(bType, TypeFactory.TYPE_OF_OBJECT, context) == null) {
        GeneratedObjectFactory objectFactory = objectFactoryGenerator.build(bType, aType, context);
        registerObjectFactory(objectFactory, (Type<Object>) bType);
    }
}

As I do not have in mind all the potential impacts of a change on those parts of the code I would rather let you examine the situation + current build is failed so more difficult to see a potential regression if I request a pull with a fix.

Upgrade ConcurrentLinkedHashMap

Orika currently uses 1.2_jdk5, which was the last Java 5 backport provided. I assume by now Orika can require Java 6 minimum and upgrade to 1.4.2. The primary benefit would be performance and using a supported version.

Its worth noting that no future releases of ConcurrentLinkedHashMap are planned. Much of it was ported/evolved into Google's Guava Cache, though with a loss of performance, which has also reached a phase of being maintenance only. A Java 8 reboot, Caffeine, is in active development. It provides high performance, a near optimal hit rate, and a variety of features. A brief overview is in the article Add a Boost of Caffeine to Your Java. When Orika is Java 8 minimum, please consider upgrading to Caffeine.

Named ClassMaps

I am looking to use Orika to map between a JDBC ResultSet and various beans (theoretically the ideal use case for Orika). However, as each ResultSet may have a variable number of columns and since the ResultSet throws an abortive SQLException if a given column is missing, it is necessary to construct a ClassMap and BoundMapperFacade for each unique ResultSet regardless if one has already been constructed for the given type.

To my immense despair, Orika seems to only allow for one ClassMap/BoundMapperFacade for each pair of types per MapperFactory. For my use case, this requires creating a new MapperFactory for each ResultSet variant -which is highly undesirable and largely defeats the purpose of the MapperFactory.

Is there something I am missing? If not, would it be possible to allow for named ClassMaps with corresponding BoundMapperFacades?

(1.4.6) Invalid code generated when embedded field name not a valid java variable name

I am experiencing a code generation problem when embedded field map key is not a valid java identifier.

For example, if I map between two classes:

Class A {
    private Map<String, List<String>> mapSource;
}

Class B {
    private Set<String> targetSet;
} 

as:

mapperFactory.classMap(A.class, B.class).field("mapSource['foo//bar']", "targetSet").register(); 

The java created attempts to make use of the key name as a variable in the mapBtoA. That generates something along the lines of:

...
if (!(((java.util.Set) source.getTargetSet()) == null)) {
      java.util.List new_foo//bar = ((java.util.List)new java.util.ArrayList(((java.util.Set)source.getTargetSet()).size()));

      new_foo//bar.addAll(mapperFacade.mapAsList(((java.util.Set)source.getTargetSet()), ((ma.glasnost.orika.metadata.Type)usedTypes[0]), ((ma.glasnost.orika.metadata.Type)usedTypes[0]), mappingContext));
    ((java.util.Map) destination.getMultiValues()).put("foo//bar", new_foo//bar);
}
... 

It looks the the name used for the intermediate variable needs to scrubbed to be a valid java variable name when the code is generated.

Incorrect mapper code generated for mapping from a single property to property of collection element

Orika 1.4.6
Origin: http://stackoverflow.com/q/35084727/466738

Test case:

public class A {
    String stringA;

    public String getStringA() {
        return stringA;
    }

    public void setStringA(String stringA) {
        this.stringA = stringA;
    }
}

public class B {
    Set<BSetElement> elements = new HashSet<>();

    public Set<BSetElement> getElements() {
        return elements;
    }

    public void setElements(Set<BSetElement> elements) {
        this.elements = elements;
    }
}

public class BSetElement {
    String stringB;

    public String getStringB() {
        return stringB;
    }

    public void setStringB(String stringB) {
        this.stringB = stringB;
    }
}

// ---- test
// assertions from import static org.assertj.core.api.Assertions.*;

    @Test
    public void test() {
        MapperFactory mapperFactory = new DefaultMapperFactory.Builder().build();
        mapperFactory.classMap(A.class, B.class)
                .field("stringA", "elements{stringB}")
                .register();
        A a = new A();
        a.setStringA("test");

        B b = mapperFactory.getMapperFacade().map(a, B.class);

        assertThat(b.getElements()).extracting("stringB").containsExactly("test");
    }

Error:

15:28:57.213 [main] DEBUG m.g.orika.metadata.ClassMapBuilder - ClassMap created:
    ClassMapBuilder.map(A, B)
     .field( stringA(String), elements{stringB}(String) )
15:28:57.694 [main] DEBUG m.g.o.impl.generator.MapperGenerator - Generating new mapper for (A, B)
    Orika_B_A_Mapper21832028326451$0.mapAToB(A, B) {
     Field(stringA(String), elements{stringB}(String)) : copying String by reference
    }
    Orika_B_A_Mapper21832028326451$0.mapBToA(B, A) {
     Field(elements{stringB}(String), stringA(String)) : copying String by reference
    }
15:28:57.698 [main] DEBUG m.g.orika.impl.MapperFacadeImpl - MappingStrategy resolved and cached:
    Inputs:[ sourceClass: orika.A, sourceType: null, destinationType: class orika.B]
    Resolved:[ strategy: InstantiateAndUseCustomMapperStrategy, sourceType: A, destinationType: B, mapper: GeneratedMapper<A, B> {usedConverters: [], usedMappers: [], usedMapperFacades: [], usedTypes: [] }, mapReverse?: false]

ma.glasnost.orika.MappingException: While attempting the following mapping:
sourceClass = class orika.A
destinationType = orika.B
resolvedStrategy = InstantiateAndUseCustomMapperStrategy<A, B> {customMapper: GeneratedMapper<A, B> {usedConverters: [], usedMappers: [], usedMapperFacades: [], usedTypes: [] }, unenhancer: ma.glasnost.orika.unenhance.BaseUnenhancer@fa49800, objectFactory: DefaultConstructorObjectFactory<B>}
Error occurred: java.lang.NullPointerException

-----begin dump of current state-----------------------------
Registered object factories: 1 (approximate size: 24.6 kB)
  [B] : {A=DefaultConstructorObjectFactory<B>}
-------------------------------------------------------------
Registered mappers: 1 (approximate size: 4,108.0 kB)
  [0] : GeneratedMapper<A, B> {usedConverters: [], usedMappers: [], usedMapperFacades: [], usedTypes: [] }
-------------------------------------------------------------
Registered concrete types: 5 (approximate size: 108.8 kB)
  [interface java.util.Collection] : ArrayList<Object>
  [interface java.util.Map] : LinkedHashMap<Object, Object>
  [interface java.util.Set] : LinkedHashSet<Object>
  [interface java.util.List] : ArrayList<Object>
  [interface java.util.Map$Entry] : MapEntry<Object, Object>
-------------------------------------------------------------
Resolved strategies: 1 (approximate size: 4,625.6 kB)
{source: A, dest: B, in-place:false}: InstantiateAndUseCustomMapperStrategy<A, B> {customMapper: GeneratedMapper<A, B> {usedConverters: [], usedMappers: [], usedMapperFacades: [], usedTypes: [] }, unenhancer: ma.glasnost.orika.unenhance.BaseUnenhancer@fa49800, objectFactory: DefaultConstructorObjectFactory<B>}
-------------------------------------------------------------
Unenhance strategy: ma.glasnost.orika.unenhance.BaseUnenhancer@fa49800
-----end dump of current state-------------------------------
    at ma.glasnost.orika.impl.ExceptionUtility.newMappingException(ExceptionUtility.java:55)
    at ma.glasnost.orika.impl.MapperFacadeImpl.map(MapperFacadeImpl.java:752)
    at ma.glasnost.orika.impl.MapperFacadeImpl.map(MapperFacadeImpl.java:721)
    at orika.OrikaTest.test(OrikaTest.java:42)
[...]
Caused by: java.lang.NullPointerException
    at ma.glasnost.orika.generated.Orika_B_A_Mapper22107286298521$0.mapAtoB(Orika_B_A_Mapper22107286298521$0.java:20)
    at ma.glasnost.orika.impl.mapping.strategy.UseCustomMapperStrategy.map(UseCustomMapperStrategy.java:67)
    at ma.glasnost.orika.impl.MapperFacadeImpl.map(MapperFacadeImpl.java:742)
    ... 29 more

It seems the generated code is incorrect:

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

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

        super.mapAtoB(a, b, mappingContext);

        // sourceType: A
        orika.A source = ((orika.A) a);
        // destinationType: B
        orika.B destination = ((orika.B) b);

        java.util.Set new_destinationElements0 = null;
        new_destinationElements0 = null;
        orika.BSetElement elements_destination0Element = null;
        boolean elements_destination0ElementShouldBeAddedToCollector = false;
/* 20: */   elements_destination0Element.setStringB(((java.lang.String) source
                .getStringA()));
        if (!(new_destinationElements0 == null)
                && !new_destinationElements0.isEmpty()) {
            if (((java.util.Set) destination.getElements()) == null) {
                destination
                        .setElements(((java.util.Set) new java.util.LinkedHashSet()));
            } else {

                ((java.util.Set) destination.getElements()).clear();
            }

            ((java.util.Set) destination.getElements())
                    .addAll(new_destinationElements0);
        }

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

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

It's clear that elements_destination0Element is null at line 20 as declared and assigned 2 lines above.
The same error happens if the collection property is of type List.

CustomConverter does not support parameterized types on subclasses

I have the following custom converter:

public class EntityToStringIdConverter<T extends BaseEntity<Long>> extends CustomConverter<T, String> {
...
}

Note that BaseEntity is a parameterized interface I have in my application.

I then register this converter as a custom converter, but it does not convert my fields. I have found out that the issue is that the CustomConverter code incorrectly detects the type T to be of type BaseEntity, and when it tries to match the type in the canConvert method it won't match for my concrete subclass (which implements BaseEntity).

The biggest problem is that I cannot customize the behavior of the CustomConverter class, since the sourceType field is final and set in the constructor. I was planning on simply passing along the actual class object for the concrete class, and set it in the sourceType. Is there a work around for this?

Orika how to configure according to the field name global ruled exclude.

Orika how to configure according to the field name global ruled exclude (hope all class exclude filed by name "errors" ใ€โ€œmetaClassโ€ ใ€ โ€œexpandoMetaClassโ€)

Such as:

      mapperFactory.classMap(Product.class, ProductDTO.class).exclude("errors").exclude("metaClass").exclude("expandoMetaClass").byDefault().register()

But I need to eliminate all class this a few properties

Orika does not map has[boolean field] as it does for is[boolean field]

Currently we can map boolean like that

    public class A  {
        private boolean blue;

        public boolean isBlue() {
            return blue;
        }

        public void setBlue(boolean blue) {
            this.blue = blue;
        }
    }

to

    public class B  {
        private boolean blue;

        public boolean isBlue() {
            return blue;
        }

        public void setBlue(boolean blue) {
            this.blue = blue;
        }
    }

But we cannot map automatically "has" boolean like this

    public class A  {
        private boolean access;

        public boolean hasAccess() {
            return access;
        }

        public void setAccess(boolean access) {
            access = access;
        }
    }

to

    public class B  {
        private boolean access;

        public boolean hasAccess() {
            return access;
        }

        public void setAccess(boolean access) {
            access = access;
        }
    }

We have to map those kind of boolean fields using a custom mapper

ClassLoader strategy coherency

Hi,

I'm currently trying to use Orika in an OSGI container. I managed to have it working but I had to make an update to Orika source code itself.

Almost, everywhere in Orika core, the ClassLoader is retrieved by using Thread.currentThread().getContextClassLoader().

I can easily get around this by setting the current tread class loader to the bundle one before calling Orika BUT in one location, the classloader is NOT retrieved from the current thread making my trick useless : JavassistCompilerStrategy (line 254)

compiledClass = byteCodeClass.toClass(this.getClass().getClassLoader(),this.getClass().getProtectionDomain());

Changing this class to make it use the same strategy (current thread class loader) as everywhere else would make it possible to use Orika more easily in an OSGI container (at least without having to have your own in-house build)

Mapping between Map<a, Map<b, c>> causes null pointer exception

Using orika 1.4.6

public class Class1 {
    private Map<String, Map<Integer, Integer>> a;
    ...
}

public class Class2 {
    private Map<String, Map<Integer, Integer>> a;
    ...
}

mapperFactory.classMap(Class1.class, Class2.class).byDefault().register();

The code above produces an exception like this:

Caused by: ma.glasnost.orika.MappingException: While attempting the following mapping:
sourceType = Class1
sourceProperty = a(Map<String, Map>)
destinationType = Class2
destinationProperty = a(Map<String, Map>)
Error occurred: java.lang.NullPointerException
    at ma.glasnost.orika.impl.generator.MapperGenerator.addMapMethod(MapperGenerator.java:177)
    at ma.glasnost.orika.impl.generator.MapperGenerator.build(MapperGenerator.java:72)
    ... 65 more
Caused by: java.lang.NullPointerException
    at ma.glasnost.orika.impl.generator.VariableRef.isPrimitive(VariableRef.java:138)
    at ma.glasnost.orika.impl.generator.VariableRef.<init>(VariableRef.java:78)
    at ma.glasnost.orika.impl.generator.specification.MapToMap.generateMappingCode(MapToMap.java:72)
    at ma.glasnost.orika.impl.generator.SourceCodeContext.mapFields(SourceCodeContext.java:768)
    at ma.glasnost.orika.impl.generator.specification.MapToMap.generateMappingCode(MapToMap.java:81)
    at ma.glasnost.orika.impl.generator.SourceCodeContext.mapFields(SourceCodeContext.java:768)
    at ma.glasnost.orika.impl.generator.MapperGenerator.generateFieldMapCode(MapperGenerator.java:251)
    at ma.glasnost.orika.impl.generator.MapperGenerator.addMapMethod(MapperGenerator.java:174)
    ... 66 more

Orika in Felix (OSGi)

Hi,

I tried to use Orika in my OSGi setup, but didn't get it to work.
I'm using Felix 5.0 and everytime I try to resolve the dependencies for my small setup it complains about missing the package com.sun.jdi, which is used by javaassist, which is used by orika.

Has anyone tried to setup Orika in an OSGi Environment yet, and was successful in doing so?

Any advice is highly appreciated ;)

Best regards,
Thomas

TypeFactory doesn't resolve the real Type Argument for parameterized type.

Given the following class hierarchy:

public class Parent<T> {
    private T content;
    public T getContent() { return content; }
    public void setContent(T content) { this.content = content; }
}

public static class Child extends Parent<Map<String, Element>> {    }

When using IntrospectorPropertyResolver to resolve the property "content" on child, we got a StackOverflowError.

The problem came from TypeUtil#resolveActualTypeArguments. That validate the typeArguments only with Class, it should validate ParametizedType too.
To support that, line 79 should be :

  if (typeArg instanceof ParameterizedType || typeArg instanceof Class) {

We create a branch to validate that and test it, want me to create a pull request with it?

mapNullsInReverse(false) at global level

Today there is a global way to tell Orika to not map nulls values :
DefaultMapperFactory.Builder().mapNulls(false)

But there is no global equivalent for the "reverse" way, it could be for instance something like :
DefaultMapperFactory.Builder().mapNullsInReverse(false)

Could the method mapNullsInReverse() be created on DefaultMapperFactory.Builder() ?

Customize mapping for annotated fields

Hi!

Is there a way to customize orika to customize the mapping for field annotated with a specific annotation?

For exemple, I would like to map differently a property annotated with @JcrReference instead of other one that doesn't have this annotation?

Thank you in advance for your help

Kevin

Error when base interface has methods with default implementations

Hi.
When I trying to perform mapping in following test:

public interface BaseA {

 default String getId() {
 return "test";
 }

 default void setId(String val) {
 }
}

public class A implements BaseA {
}

public class B {
 @Getter
 @Setter
 String id;
}

@Test
public void defaultInterfaceImplementationsTest() {
 val mapperFactory = new DefaultMapperFactory.Builder().build();

 mapperFactory.classMap(A.class, B.class)
 .byDefault()
 .register();

 A a = new A();
 B b = new B();

 mapperFactory.getMapperFacade().map(a, b);
 assertThat(b, notNullValue());
}

I'm getting strange compilation error:
Caused by: compile error: getId() not found in test.unit.views.BaseViewTest$A at javassist.compiler.TypeChecker.atMethodCallCore(TypeChecker.java:723) at javassist.compiler.TypeChecker.atCallExpr(TypeChecker.java:688) at javassist.compiler.JvstTypeChecker.atCallExpr(JvstTypeChecker.java:157)

I tried to compile generated class by hands, and all seems to be ok...
This test looks a little bit synthetic, but real situation is exactly the same.
Any ideas on how I this error can be fixed?

UPD maybe JavassistCompilerStrategy don't support java 1.8 by default ?

orika default mapping breaks when registering classMap with only byDefault()

In oasp.io we actually created a facade for bean mappers such as dozer, orika, or MapStruct to prevent coupling to an fixed implementation and the being bound to it. We started with Dozer but want to switch to Orika as default. However, we are facing a strange issue:
The default mapping of Orika works but we want to add a specific custom mapping. Doing so broke the default mapping and our test. I now discovered that already adding the classMap for my A/B mapping with mapper.classMap(A.class, B.class).byDefault().register() already breaks the defaults and prevents some fields from being mapped.

Here is our test-case on github if you want to have a look (the use-case is quite simple so I am surprised that orika already fails with this setup, but we might do something wrong):
https://github.com/oasp/oasp4j/blob/develop/oasp4j-modules/oasp4j-beanmapping/src/test/java/io/oasp/module/beanmapping/common/impl/BeanMapperImplOrikaTest.java

Strange behaviour with fieldMap("", "foo") in 1.4.4

We have seen some strange behaviour that we're not able to reproduce.

mapper = mapperFactory.getMapperFacade(CustomerLookUp.class, InsurancePartyLookup.class);
mapperFactory.classMap(CustomerLookUp.class, InsurancePartyLookup.class).
        field("", "person").
        byDefault().
        register();

We have unit tests that runs through this and it always succeeds. In production we have a WAS8 cluster with four nodes. Sometimes we have seen that on one of these nodes, the above mapping starts to return null, and then we just have to restart the module. We can see from the logs that the input is not null.

It doesn't happen very often though, but we've seen it both in production and in our test environments from time to time. Now we have replaced this particular mapping with a "manual mapping". This example is the only place in our codebase where we have used the field method with the first parameter being just an empty string.

We use spring to create our MapperFactory, like this:

<bean id="MapperFactoryBuilder" class="ma.glasnost.orika.impl.DefaultMapperFactory.Builder" />
<bean id="MapperFactory" factory-bean="MapperFactoryBuilder" factory-method="build" />

This is not critical for us since we already have bypassed the bug, but anyway I felt I should at least inform you guys about this. Please ask if you need more details.

Loses values when mapping List<> to Map<>. Works the other way around.

Given is the following configuration:

mapperFactory.classMap(new TypeBuilder<Map<String, String>>() {}.build(), new TypeBuilder<List<com.ebcont.gtv.atypon.online.wsstubs.phase2.KeyValue>>() {}.build())
        .field("{key}", "{key}")
        .field("{value}", "{value}")
        // for debugging purpose
        .customize(new CustomMapper<Map<String, String>, List<KeyValue>>() {
            @Override
            public void mapAtoB(Map<String, String> stringStringMap, List<KeyValue> keyValues, MappingContext context) {
                super.mapAtoB(stringStringMap, keyValues, context);
            }

            @Override
            public void mapBtoA(List<KeyValue> keyValues, Map<String, String> stringStringMap, MappingContext context) {
                super.mapBtoA(keyValues, stringStringMap, context);
            }
        })
        .register();

KeyValue is:

public class KeyValue {

    protected String key;
    protected String value;

    public String getKey() {
        return key;
    }

    public void setKey(String value) {
        this.key = value;
    }

    public String getValue() {
        return value;
    }

    public void setValue(String value) {
        this.value = value;
    }
}

Works fine, when mapping an Object with a Map<String, String> Property to an Object with a List<KeyValue> Property. The other way around, the resulting Map<String, String> will be empty. Although the stringStringMap in mapBtoA in the CustomMapper is correct and contains all values.

Mapping does not trigger destination filtering

In my quest to find a way to do generic collection merging based on field names (I need to be able to do this on a variety of classes where we take the name of the field as input at runtime, so custom mapper isn't much help here) I was investigating filters. While it may not be the intended usage it seems like it should have all the hooks necessary to accomplish this, but when I try to create a filter the mapping framework doesn't seem to ever call the filterDestination method even though I can see the filter has been registered and other methods called. Please see this test case as an example.

package com.example;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import ma.glasnost.orika.BoundMapperFacade;
import ma.glasnost.orika.MapperFactory;
import ma.glasnost.orika.MappingContext;
import ma.glasnost.orika.NullFilter;
import ma.glasnost.orika.impl.DefaultMapperFactory;
import ma.glasnost.orika.metadata.Type;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;


public class DestinationFilterNotCalledTest {

    private BoundMapperFacade<SimpleObject, SimpleObject> mapper;

    @Before
    public void setUp() {
        MapperFactory mapperFactory = new DefaultMapperFactory.Builder().build();
        mapperFactory.classMap(SimpleObject.class, SimpleObject.class)
            .mapNulls(false)
            .fieldMap("aliases").add()
            .register();

        mapperFactory.registerFilter(new MergingFilter());
        mapper = mapperFactory.getMapperFacade(SimpleObject.class, SimpleObject.class);
    }

    @Test
    public void testDestinationFiltering() {
        SimpleObject obj1 = new SimpleObject();
        obj1.setName("John");
        obj1.setAliases(Arrays.asList("Jon", "Johnny"));

        SimpleObject obj2 = new SimpleObject();
        obj2.setName("John");
        obj2.setAliases(Arrays.asList("JJ"));

        mapper.map(obj1, obj2);
        Assert.assertEquals(3, obj2.getAliases().size());
    }


    public static class MergingFilter extends NullFilter<List<String>, List<String>> {

        @Override
        public <S extends List<String>, D extends List<String>> boolean shouldMap(Type<S> sourceType, String sourceName, S source, Type<D> destType, String destName, D dest, MappingContext mappingContext) {
            System.out.println("Calling should map");

            mappingContext.setProperty("toMergeFrom", source);
            mappingContext.setProperty("toMergeTo", dest);

            return true;
        }

        @Override
        public <D extends List<String>> D filterDestination(D destinationValue, Type<?> sourceType, String sourceName, Type<D> destType, String destName, MappingContext mappingContext) {
            System.out.println("Calling filter destination");
            List<String> origSourceValue = (List<String>)mappingContext.getProperty("toMergeFrom");
            List<String> origDestValue = (List<String>)mappingContext.getProperty("toMergeTo");

            origDestValue.forEach(val -> {
                if (!destinationValue.contains(val)) {
                    destinationValue.add(val);
                }
            });
            return destinationValue;
        }

        @Override
        public boolean filtersDestination() {
            return true;
        }
    }


    public static class SimpleObject {
        private String name;
        private List<String> aliases = new ArrayList<>();

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public List<String> getAliases() {
            return aliases;
        }

        public void setAliases(List<String> aliases) {
            this.aliases = aliases;
        }
    }
}

compile error: no such field: java

I have a JAXB generated field. whose datatype is "Double". when i try to map this field using Orika, I am getting the error(compile error: no such field: java). However it is working fine if i change it from (Double) to primitive type (double).

Here is the mapping of my nested class element
.field("employmentDetails.incomes{netIncomeAmount}", "employerList{incomeType.netIncome}")

I defined "netIncomeAmount" as xs:double. XJC generated the field as "Double". while mapping the fields, orika throws the compile error: no such field: java exception.

I appreciate any comments.

Thanks
Vasu

Deadlock with Orika 1.4.4

I've had a deadlock using Orika 1.4.4 when getting a MapperFacade from a DefaultMapperFactory. This is the deadlock threads dump:

"Thread-18":
    at ma.glasnost.orika.impl.DefaultMapperFactory.getMapperFacade(DefaultMapperFactory.java:721)
    - waiting to lock <0x00000007a7b3f708> (a ma.glasnost.orika.impl.MapperFacadeImpl)
    at ma.glasnost.orika.impl.DefaultBoundMapperFacade.<init>(DefaultBoundMapperFacade.java:77)
    at ma.glasnost.orika.impl.DefaultMapperFactory.getMapperFacade(DefaultMapperFactory.java:1316)
    at ma.glasnost.orika.impl.DefaultMapperFactory.getMapperFacade(DefaultMapperFactory.java:1301)
    at ma.glasnost.orika.impl.generator.UsedMapperFacadesContext.getIndex(UsedMapperFacadesContext.java:72)
    at ma.glasnost.orika.impl.generator.SourceCodeContext.usedMapperFacadeCall(SourceCodeContext.java:308)
    at ma.glasnost.orika.impl.generator.SourceCodeContext.callMapper(SourceCodeContext.java:331)
    at ma.glasnost.orika.impl.generator.SourceCodeContext.callMapper(SourceCodeContext.java:349)
    at ma.glasnost.orika.impl.generator.specification.ObjectToObject.generateMappingCode(ObjectToObject.java:44)
    at ma.glasnost.orika.impl.generator.SourceCodeContext.mapFields(SourceCodeContext.java:762)
    at ma.glasnost.orika.impl.generator.MapperGenerator.generateFieldMapCode(MapperGenerator.java:249)
    at ma.glasnost.orika.impl.generator.MapperGenerator.addMapMethod(MapperGenerator.java:172)
    at ma.glasnost.orika.impl.generator.MapperGenerator.build(MapperGenerator.java:70)
    at ma.glasnost.orika.impl.DefaultMapperFactory.buildMapper(DefaultMapperFactory.java:1190)
    at ma.glasnost.orika.impl.DefaultMapperFactory.build(DefaultMapperFactory.java:1049)
    - locked <0x00000007a5d99028> (a ma.glasnost.orika.impl.DefaultMapperFactory)
    at ma.glasnost.orika.impl.DefaultMapperFactory.getMapperFacade(DefaultMapperFactory.java:1313)
    at ma.glasnost.orika.impl.DefaultMapperFactory.getMapperFacade(DefaultMapperFactory.java:1301)
    at ma.glasnost.orika.impl.DefaultMapperFactory.getMapperFacade(DefaultMapperFactory.java:1326)
    at com.tuenti.platform.scheduler.quartz.config.CronJobConfigurator.getJobParams(CronJobConfigurator.java:170)
    at com.tuenti.platform.scheduler.quartz.config.CronJobConfigurator.createQuartzJob(CronJobConfigurator.java:116)
    at com.tuenti.platform.scheduler.quartz.config.CronJobConfigurator.reconfigure(CronJobConfigurator.java:68)
    at com.tuenti.platform.scheduler.quartz.config.SynchronizedQuartzConfigurator.reconfigure(SynchronizedQuartzConfigurator.java:66)
    at com.tuenti.platform.scheduler.quartz.ConfigChecker.reconfigure(ConfigChecker.java:67)
    at com.tuenti.platform.scheduler.quartz.ConfigChecker.run(ConfigChecker.java:56)
"localhost-startStop-1":
    at ma.glasnost.orika.impl.DefaultMapperFactory.build(DefaultMapperFactory.java:1035)
    - waiting to lock <0x00000007a5d99028> (a ma.glasnost.orika.impl.DefaultMapperFactory)
    at ma.glasnost.orika.impl.DefaultMapperFactory.getMapperFacade(DefaultMapperFactory.java:722)
    - locked <0x00000007a7b3f708> (a ma.glasnost.orika.impl.MapperFacadeImpl)
    at com.tuenti.platform.di.OrikaModule.provideMapperFacade(OrikaModule.java:37)
    at com.tuenti.platform.di.OrikaModule$$FastClassByGuice$$523b1b18.invoke(<generated>)
    at com.google.inject.internal.ProviderMethod$FastClassProviderMethod.doProvision(ProviderMethod.java:229)
    at com.google.inject.internal.ProviderMethod.get(ProviderMethod.java:147)
    at com.google.inject.internal.ProviderInternalFactory.provision(ProviderInternalFactory.java:86)
    at com.google.inject.internal.InternalFactoryToInitializableAdapter.provision(InternalFactoryToInitializableAdapter.java:54)
    at com.google.inject.internal.ProviderInternalFactory.circularGet(ProviderInternalFactory.java:66)
    at com.google.inject.internal.InternalFactoryToInitializableAdapter.get(InternalFactoryToInitializableAdapter.java:46)
    at com.google.inject.internal.SingleParameterInjector.inject(SingleParameterInjector.java:38)
    at com.google.inject.internal.SingleParameterInjector.getAll(SingleParameterInjector.java:62)
    at com.google.inject.internal.ConstructorInjector.provision(ConstructorInjector.java:107)
    at com.google.inject.internal.ConstructorInjector.construct(ConstructorInjector.java:88)
    at com.google.inject.internal.ConstructorBindingImpl$Factory.get(ConstructorBindingImpl.java:279)
    at com.google.inject.internal.FactoryProxy.get(FactoryProxy.java:56)
    at com.google.inject.internal.SingleParameterInjector.inject(SingleParameterInjector.java:38)
    at com.google.inject.internal.SingleParameterInjector.getAll(SingleParameterInjector.java:62)
    at com.google.inject.internal.ConstructorInjector.provision(ConstructorInjector.java:107)
    at com.google.inject.internal.ConstructorInjector.construct(ConstructorInjector.java:88)
    at com.google.inject.internal.ConstructorBindingImpl$Factory.get(ConstructorBindingImpl.java:279)
    at com.google.inject.internal.ProviderToInternalFactoryAdapter$1.call(ProviderToInternalFactoryAdapter.java:46)
    at com.google.inject.internal.InjectorImpl.callInContext(InjectorImpl.java:1065)
    at com.google.inject.internal.ProviderToInternalFactoryAdapter.get(ProviderToInternalFactoryAdapter.java:40)
    at com.google.inject.Scopes$1$1.get(Scopes.java:59)
    - locked <0x00000007a5f50728> (a com.google.inject.Scopes$1$1)
    at com.google.inject.internal.InternalFactoryToProviderAdapter.get(InternalFactoryToProviderAdapter.java:41)
    at com.google.inject.internal.InjectorImpl$2$1.call(InjectorImpl.java:1008)
    at com.google.inject.internal.InjectorImpl.callInContext(InjectorImpl.java:1058)
    at com.google.inject.internal.InjectorImpl$2.get(InjectorImpl.java:1004)
    at com.google.inject.internal.InjectorImpl.getInstance(InjectorImpl.java:1039)
    at com.google.inject.servlet.ServletDefinition.init(ServletDefinition.java:117)
    at com.google.inject.servlet.AbstractServletPipeline.init(AbstractServletPipeline.java:52)
    at com.google.inject.servlet.AbstractFilterPipeline.initPipeline(AbstractFilterPipeline.java:79)
    - locked <0x00000007a6208748> (a com.google.inject.servlet.ManagedFilterPipeline)
    at com.google.inject.servlet.GuiceFilter.init(GuiceFilter.java:220)
    at org.apache.catalina.core.ApplicationFilterConfig.initFilter(ApplicationFilterConfig.java:277)
    at org.apache.catalina.core.ApplicationFilterConfig.getFilter(ApplicationFilterConfig.java:258)
    at org.apache.catalina.core.ApplicationFilterConfig.setFilterDef(ApplicationFilterConfig.java:382)
    at org.apache.catalina.core.ApplicationFilterConfig.<init>(ApplicationFilterConfig.java:103)
    at org.apache.catalina.core.StandardContext.filterStart(StandardContext.java:4649)
    - locked <0x00000007a5c17480> (a java.util.HashMap)
    at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5305)
    - locked <0x00000007a591e718> (a org.apache.catalina.core.StandardContext)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
    - locked <0x00000007a591e718> (a org.apache.catalina.core.StandardContext)
    at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:899)
    at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:875)
    at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:618)
    at org.apache.catalina.startup.HostConfig.deployWAR(HostConfig.java:963)
    at org.apache.catalina.startup.HostConfig$DeployWar.run(HostConfig.java:1600)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)
    at java.util.concurrent.FutureTask.run(FutureTask.java:262)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at java.lang.Thread.run(Thread.java:744)

Found 1 deadlock.

Inject security check

Hi,
I did mapping with Orika and it's working perfect, so I have next task.
I have two objects of same class and I need a copy values from one to other and make security check for each.
Like this: securityCheck(PropertyNameOrSomething prop, Object srcValue, Object dstValue) {...}
To make decision if mapping is allowed I need some propertyDescription and property values of both objects.

Please, can you advice where I can extend Orika to make this checking possible?

reopen issue #143:

Found this older issue which I am seeing in the latest release: 1.4.6

https://code.google.com/archive/p/orika/issues/143

Test case from the post that shows the issue:

package ma.glasnost.orika.test.community;

import ma.glasnost.orika.MapperFacade;
import ma.glasnost.orika.MapperFactory;
import ma.glasnost.orika.impl.DefaultMapperFactory;
import org.junit.Assert;
import org.junit.Test;

public class AbstractCircularReferenceTestCase {
    @Test
    public void test() {
        DefaultMapperFactory.Builder builder = new DefaultMapperFactory.Builder();
        MapperFactory factory = builder.build();
        factory.classMap(Entity.class, BaseEntity.class).field("anotherEntity", "anotherBaseEntity").register();
        factory.classMap(AnotherEntity.class, AnotherBaseEntity.class).field("abstractEntity", "abstractBaseEntity").register();

        MapperFacade mapperFacade = factory.getMapperFacade();

        Entity entity = new Entity();

        AnotherEntity anotherEntity = new AnotherEntity();
        anotherEntity.setAbstractEntity(entity);

        entity.setAnotherEntity(anotherEntity);


        BaseEntity baseEntity = mapperFacade.map(entity, BaseEntity.class);

        Assert.assertEquals(entity, entity.getAnotherEntity().getAbstractEntity());
        Assert.assertEquals(baseEntity, baseEntity.getAnotherBaseEntity().getAbstractBaseEntity());
    }

    public static abstract class AbstractEntity {
        AnotherEntity anotherEntity;

        public AnotherEntity getAnotherEntity() {
            return anotherEntity;
        }

        public void setAnotherEntity(AnotherEntity anotherEntity) {
            this.anotherEntity = anotherEntity;
        }
    }

    public static class Entity extends AbstractEntity {
    }

    public static class AnotherEntity {
        AbstractEntity abstractEntity;

        public AbstractEntity getAbstractEntity() {
            return abstractEntity;
        }

        public void setAbstractEntity(AbstractEntity abstractEntity) {
            this.abstractEntity = abstractEntity;
        }
    }

    public static class AbstractBaseEntity {
        AnotherBaseEntity anotherBaseEntity;

        public AnotherBaseEntity getAnotherBaseEntity() {
            return anotherBaseEntity;
        }

        public void setAnotherBaseEntity(AnotherBaseEntity anotherBaseEntity) {
            this.anotherBaseEntity = anotherBaseEntity;
        }
    }

    public static class BaseEntity extends AbstractBaseEntity {
    }

    public static class AnotherBaseEntity {
        AbstractBaseEntity abstractBaseEntity;

        public AbstractBaseEntity getAbstractBaseEntity() {
            return abstractBaseEntity;
        }

        public void setAbstractBaseEntity(AbstractBaseEntity abstractBaseEntity) {
            this.abstractBaseEntity = abstractBaseEntity;
        }
    }
}

I can see that converting a list of abstract types will:

  1. check the typeCache keying off abstract type
  2. fail to find it and resolve the concrete destination type
  3. check the typeCache again with correct destination type and is successful

however single objects (use aToB converting) do not attempt to resolve the concrete destination type until after checking the typeCache:

  1. check the typeCache keying off abstract type
  2. fail to find it and create a new instance (basically a copy)
  3. put new instance in the typeCache (now typeCache has 2 objects that are identical in contents but different instances)

RamUsageEstimator fails with ClassNotFound

As the title already says the RamUsageEstimator fails with ClassNotFound when inspecting the objectFactoryRegistry (see Stacktrace below). This in turn hides the real Exception in the mapping. State reporting should not fail with exceptions caused by it or its underlying tools. I guess this has to do with something funny with the classloader.

There is already a property for DUMP_STATE_ON_EXCEPTION maybe another one would make sense INCLUDE_SIZE_IN_STATE_DUMP, which would control the inclusion of the RamUsageEstimator.

java.lang.ClassNotFoundException: com.private.Representation
      at java.net.URLClassLoader.findClass(URLClassLoader.java:381) ~[na:1.8.0_66]
      at java.lang.ClassLoader.loadClass(ClassLoader.java:424) ~[na:1.8.0_66]
      at java.lang.ClassLoader.loadClass(ClassLoader.java:357) ~[na:1.8.0_66]
      at java.lang.Class.getDeclaredFields0(Native Method) ~[na:1.8.0_66]
      at java.lang.Class.privateGetDeclaredFields(Class.java:2583) ~[na:1.8.0_66]
      at java.lang.Class.getDeclaredFields(Class.java:1916) ~[na:1.8.0_66]
      at com.carrotsearch.sizeof.RamUsageEstimator.createCacheEntry(RamUsageEstimator.java:568) ~[java-sizeof-0.0.4.jar:na]
      at com.carrotsearch.sizeof.RamUsageEstimator.measureSizeOf(RamUsageEstimator.java:532) ~[java-sizeof-0.0.4.jar:na]
      at com.carrotsearch.sizeof.RamUsageEstimator.sizeOfAll(RamUsageEstimator.java:380) ~[java-sizeof-0.0.4.jar:na]
      at com.carrotsearch.sizeof.RamUsageEstimator.sizeOfAll(RamUsageEstimator.java:361) ~[java-sizeof-0.0.4.jar:na]
      at ma.glasnost.orika.StateReporter.humanReadableSizeInMemory(StateReporter.java:48) ~[orika-core-1.4.6.jar:na]
      at ma.glasnost.orika.impl.DefaultMapperFactory.reportCurrentState(DefaultMapperFactory.java:1559) ~[orika-core-1.4.6.jar:na]
      at ma.glasnost.orika.StateReporter.reportCurrentState(StateReporter.java:33) ~[orika-core-1.4.6.jar:na]
      at ma.glasnost.orika.impl.ExceptionUtility.decorate(ExceptionUtility.java:65) ~[orika-core-1.4.6.jar:na]
      at ma.glasnost.orika.impl.MapperFacadeImpl.resolveMappingStrategy(MapperFacadeImpl.java:209) ~[orika-core-1.4.6.jar:na]
      at ma.glasnost.orika.impl.MapperFacadeImpl.map(MapperFacadeImpl.java:741) ~[orika-core-1.4.6.jar:na]
      at ma.glasnost.orika.impl.MapperFacadeImpl.map(MapperFacadeImpl.java:721) ~[orika-core-1.4.6.jar:na]
      at ma.glasnost.orika.impl.ConfigurableMapper.map(ConfigurableMapper.java:150) ~[orika-core-1.4.6.jar:na]
...

Another weird thing I noticed when logging all classes the RamUsageEstimator looks at, is that it looks at way too many classes in com.carrotsearch.sizeof.RamUsageEstimator#createCacheEntry which should not be part of the mapping.

No concrete class mapping defined error mapping a list of interfaces

I get a no concrete class mapping defined error when mapping a class containing a list of interface B containing a concrete class C implementig B:

ma.glasnost.orika.MappingException: While attempting the following mapping:
sourceType = TestCase.C
destinationType = TestCase.B
Error occurred: No concrete class mapping defined for source class TestCase$C

Used Version: 1.4.6

Test Case:

import java.util.ArrayList;
import java.util.List;

import ma.glasnost.orika.MapperFacade;
import ma.glasnost.orika.MapperFactory;
import ma.glasnost.orika.impl.DefaultMapperFactory;

import org.junit.Assert;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class TestCase {

    protected final Logger logger = LoggerFactory.getLogger(getClass());

    @Test
    public void test() {
        logger.trace("test() - begin");
        try {
            final MapperFactory mapperFactory = new DefaultMapperFactory.Builder()
                    .build();
            final MapperFacade mapperFacade = mapperFactory.getMapperFacade();

            A a = new A();

            B b = new C();
            b.setName("pippo");

            a.getList().add(b);

            A out = mapperFacade.map(a, A.class);

            Assert.assertNotNull(out);

        } catch (Exception e) {
            logger.error("test() - Exception Thrown: " + e.toString(), e);
            Assert.fail(e.toString());
        }
        logger.trace("test() - end");
    }

    public static class A {

        private List<B> list  = new ArrayList<B>();

        public List<B> getList() {
            return list;
        }

        public void setList(List<B> list) {
            this.list = list;
        }
    }

    public static interface B {

        public String getName();

        public void setName(String name);

    }

    public static class C implements B {

        private String name;

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

    }
}

CustomMapper ArrayIndexOutOfBoundsException if an intermediate generic superclass is used for a mapper implementation

Orika 1.4.6

I have a following class hierarchy:

class GenericSuperMapper<S> extends CustomMapper<S, MyTarget> {...}
class ConcreteMapper extends GenericSuperMapper<MySource> {...}

I get

java.lang.ArrayIndexOutOfBoundsException: 1
    at ma.glasnost.orika.CustomMapper.<init>(CustomMapper.java:45)

I would suggest in the CustomMapper constructor not to look at the direct superclass of this, but to look up the class hierarchy for the CustomMapper class and use the getActualTypeArguments() of that.

Source files without license headers

The following source files are without license headers:

./core/src/main/java/ma/glasnost/orika/StateReporter.java
./core/src/main/java/ma/glasnost/orika/constructor/ConstructorParameterResolver.java
./core/src/main/java/ma/glasnost/orika/util/Node.java
./core/src/main/java/ma/glasnost/orika/util/Edge.java

./tests/src/main/java/DefaultPackageTestCase.java
./tests/src/main/java/ma/glasnost/orika/test/boundmapperfacade/SortedMapSetTestCase.java
./tests/src/main/java/ma/glasnost/orika/test/capturefieldcontext/FieldContextWithFiltersTestCase.java
./tests/src/main/java/ma/glasnost/orika/test/community/Issue114TestCase.java
./tests/src/main/java/ma/glasnost/orika/test/community/Issue119TestCase.java
./tests/src/main/java/ma/glasnost/orika/test/community/Issue126TestCase.java
./tests/src/main/java/ma/glasnost/orika/test/community/Issue128TestCase.java
./tests/src/main/java/ma/glasnost/orika/test/community/Issue132TestCase.java
./tests/src/main/java/ma/glasnost/orika/test/community/Issue138TestCase.java
./tests/src/main/java/ma/glasnost/orika/test/community/Issue140TestCase.java
./tests/src/main/java/ma/glasnost/orika/test/community/Issue141TestCase.java
./tests/src/main/java/ma/glasnost/orika/test/community/Issue161TestCase.java
./tests/src/main/java/ma/glasnost/orika/test/community/PersonMappingTestCase.java
./tests/src/main/java/ma/glasnost/orika/test/community/issue121/Issue121TestCase.java
./tests/src/main/java/ma/glasnost/orika/test/community/issue121/aobjects/AbstractOrderedMap.java
./tests/src/main/java/ma/glasnost/orika/test/community/issue121/aobjects/AMapAObjects1.java
./tests/src/main/java/ma/glasnost/orika/test/community/issue121/aobjects/AObject1.java
./tests/src/main/java/ma/glasnost/orika/test/community/issue121/aobjects/AObject2.java
./tests/src/main/java/ma/glasnost/orika/test/community/issue121/bobjects/BContainerListBObject1.java
./tests/src/main/java/ma/glasnost/orika/test/community/issue121/bobjects/BObject1.java
./tests/src/main/java/ma/glasnost/orika/test/community/issue121/bobjects/BObject2.java
./tests/src/main/java/ma/glasnost/orika/test/community/issue121/bobjects/BObject2Container.java
./tests/src/main/java/ma/glasnost/orika/test/community/issue121/util/RandomUtils.java
./tests/src/main/java/ma/glasnost/orika/test/community/issue135/Domain.java
./tests/src/main/java/ma/glasnost/orika/test/community/issue135/Representation.java
./tests/src/main/java/ma/glasnost/orika/test/community/issue135/Issue135Test.java
./tests/src/main/java/ma/glasnost/orika/test/community/issue135/RepA.java
./tests/src/main/java/ma/glasnost/orika/test/community/issue135/RepB.java
./tests/src/main/java/ma/glasnost/orika/test/community/issue135/SubB.java
./tests/src/main/java/ma/glasnost/orika/test/community/issue135/SubA.java
./tests/src/main/java/ma/glasnost/orika/test/community/issue137/CustomFactory.java
./tests/src/main/java/ma/glasnost/orika/test/community/issue137/LevelOne.java
./tests/src/main/java/ma/glasnost/orika/test/community/issue137/LevelTest.java
./tests/src/main/java/ma/glasnost/orika/test/community/issue137/LevelThree.java
./tests/src/main/java/ma/glasnost/orika/test/community/issue137/LevelTwo.java
./tests/src/main/java/ma/glasnost/orika/test/favorsextension/FavorsExtensionTestCase.java
./tests/src/main/java/ma/glasnost/orika/test/filters/NestedPropertyFilterTest.java
./tests/src/main/java/ma/glasnost/orika/test/filters/SourceNestedFilterTest.java
./tests/src/main/java/ma/glasnost/orika/test/generator/PropertiesWithNoSetterTestCase.java
./tests/src/main/java/ma/glasnost/orika/test/unenhance/inheritance2/AbstractDto.java
./tests/src/main/java/ma/glasnost/orika/test/unenhance/inheritance2/AbstractEntity.java
./tests/src/main/java/ma/glasnost/orika/test/unenhance/inheritance2/HibernateProxyTestCase.java
./tests/src/main/java/ma/glasnost/orika/test/unenhance/inheritance2/OwnerDto.java
./tests/src/main/java/ma/glasnost/orika/test/unenhance/inheritance2/OwnerEntity.java
./tests/src/main/java/ma/glasnost/orika/test/unenhance/inheritance2/PersonDto.java
./tests/src/main/java/ma/glasnost/orika/test/unenhance/inheritance2/PersonEntity.java
./tests/src/main/java/ma/glasnost/orika/test/unenhance/inheritance2/RoomDto.java
./tests/src/main/java/ma/glasnost/orika/test/unenhance/inheritance2/RoomEntity.java

Please, confirm the licensing of code and/or content/s, and add license headers
https://fedoraproject.org/wiki/Packaging:LicensingGuidelines?rd=Packaging/LicensingGuidelines#License_Clarification

Thanks in advance
Regards

Repeated elements in collections are removed

Hi, In my case the entity Sharing has a list of User, the entity SharingDoc has an a list of userId.

public class Sharing extends BaseEntity{
  private List<User> sharedWith;
}

public class User extends BaseEntity {
  private Long id;
}
public class SharingDoc extends BaseEntity{
  private List<Long> sharedWith;
}

I have the following mapping:

mapperFactory.classMap(Sharing.class, SharingDoc.class)
  .field("sharedWith{id}", "sharedWith{}") // Test this!!
  .byDefault()
  .register();

I made a test where I create a Sharing entity with three users, the user.id are 1L, 2L and 2L (Yes, it's repeated)

Original Sharing:

{
  "sharedWith": [
    { "id": 1},
    { "id": 2},
    { "id": 2}
  ]
}

Mapped SharingDoc:

{
  "sharedWith": [
    1,
    2,
    2
  ]
}

I did the inverse mapping, so, the final Sharing entity is:

{
  "sharedWith": [
    { "id": 1},
    { "id": 2}
  ]
}

One user has disappeared. In some cases, it could be important.

Paranamer issue if Object uses lambda

FYI,

Came across an issue when trying to do mapping on Objects which uses Java 8 lambdas, I get exceptions like below.


Caused by: java.lang.ArrayIndexOutOfBoundsException: 24950
    at com.thoughtworks.paranamer.BytecodeReadingParanamer$ClassReader.accept(BytecodeReadingParanamer.java:563)
    at com.thoughtworks.paranamer.BytecodeReadingParanamer$ClassReader.access$200(BytecodeReadingParanamer.java:338)
    at com.thoughtworks.paranamer.BytecodeReadingParanamer.lookupParameterNames(BytecodeReadingParanamer.java:103)
    at com.thoughtworks.paranamer.AdaptiveParanamer.lookupParameterNames(AdaptiveParanamer.java:75)
    at com.thoughtworks.paranamer.CachingParanamer.lookupParameterNames(CachingParanamer.java:90)
    at com.thoughtworks.paranamer.CachingParanamer.lookupParameterNames(CachingParanamer.java:83)
    at ma.glasnost.orika.constructor.SimpleConstructorResolverStrategy.resolve(SimpleConstructorResolverStrategy.java:121)
    at ma.glasnost.orika.impl.generator.ObjectFactoryGenerator.addSourceClassConstructor(ObjectFactoryGenerator.java:155)
    at ma.glasnost.orika.impl.generator.ObjectFactoryGenerator.addCreateMethod(ObjectFactoryGenerator.java:123)
    at ma.glasnost.orika.impl.generator.ObjectFactoryGenerator.build(ObjectFactoryGenerator.java:94)

Someone already raised a ticket raised for paranamer paul-hammant/paranamer#17

I've tested the proposed fix for paranamer, can confirm mapping issue gets fixed for me. So I think it's worthwhile tracking paranamer for the latest release.

Filters are not applied for Collection 2 Collection Mapping

SourceCodeContext.getDestFilter and
SourceCodeContext.getSourceFilter
return VariableRef with overriden setter() and getter()
but ArrayOrCollectionToCollection.generateMappingCode uses MultiOccurrenceVariableRef decorators which dont call these setter/getter

all above causes that Filter.filterSource and Filter.filterDestination are not invoked in the generated code for collection field mapping.

Null-pointer exception

Hello,

I'm using orika to synchronize my content catalog, and I get the following null-pointer exception. It's hard to see where it's happening because I don't see any line numbers. I tried to put a breakpoint in the method but it never goes thought that method (maybe because the sources are regenerated every time). Can you please tell me how to debug it?

[INFO] Executing step: [catalog-sync]
2015-08-28 21:13:55,140 com.nemesis.platform.core.batch.processor.DefaultSyncEntityProcessor [main] ERROR: Found error synchronizing: [nemesis-social - SocialWidget]
[ERROR] Encountered an error executing step catalog-sync in job syncCatalogJob
ma.glasnost.orika.MappingException: While attempting the following mapping:
sourceClass = class com.nemesis.platform.module.widget.social.core.model.SocialWidget
destinationType = com.nemesis.platform.module.widget.social.core.model.SocialWidget
resolvedStrategy = InstantiateAndUseCustomMapperStrategy<SocialWidget, SocialWidget> {customMapper: GeneratedMapper<SocialWidget, SocialWidget> {usedConverters: [], usedMappers: [ma.glasnost.orika.impl.ReversedMapper@360fa5b0], usedMapperFacades: [], usedTypes: [LinkWidgetDefinition] }, unenhancer: ma.glasnost.orika.unenhance.BaseUnenhancer@35e5f050, objectFactory: com.nemesis.platform.core.factory.AbstractCatalogableEntityModelFactory@bec4324}
Error occurred: java.lang.NullPointerException
-----begin dump of current state-----------------------------
Registered object factories: 41 (approximate size: 162,946.1 kB)
  [ProjectProductModel] : {Object=com.nemesis.platform.core.factory.AbstractCatalogableEntityModelFactory@2ca0a769}
  [PriceModel] : {Object=com.nemesis.platform.core.factory.AbstractCatalogableEntityModelFactory@2010f2fa}
  [SelectorWidget] : {Object=com.nemesis.platform.core.factory.AbstractCatalogableEntityModelFactory@2d340045}
  [ContentSlotModel] : {Object=com.nemesis.platform.core.factory.AbstractCatalogableEntityModelFactory@33c4296}
  [SimpleBannerWidget] : {Object=com.nemesis.platform.core.factory.AbstractCatalogableEntityModelFactory@77adf6ab}
  [VoucherModel] : {Object=com.nemesis.platform.core.factory.AbstractCatalogableEntityModelFactory@3ea33204}
  [DiscountModel] : {Object=com.nemesis.platform.core.factory.AbstractCatalogableEntityModelFactory@7e7203c6}
  [LinkWidget] : {Object=com.nemesis.platform.core.factory.AbstractCatalogableEntityModelFactory@5d4622bf}
  [BlogCategoryModel] : {Object=com.nemesis.platform.core.factory.AbstractCatalogableEntityModelFactory@280d7c1b}
  [AbstractTemplateModel] : {Object=com.nemesis.platform.core.factory.AbstractCatalogableEntityModelFactory@66537be0}
  [ListerPageModel] : {Object=com.nemesis.platform.core.factory.AbstractCatalogableEntityModelFactory@2fa4cfb0}
  [CategoryListerWidget] : {Object=com.nemesis.platform.core.factory.AbstractCatalogableEntityModelFactory@70e9c880}
  [ChatWidget] : {Object=com.nemesis.platform.core.factory.AbstractCatalogableEntityModelFactory@1dea0074}
  [StockLevelModel] : {Object=com.nemesis.platform.core.factory.AbstractCatalogableEntityModelFactory@553980b8}
  [ProductCarouselWidget] : {Object=com.nemesis.platform.core.factory.AbstractCatalogableEntityModelFactory@38c03128}
  [TaxModel] : {Object=com.nemesis.platform.core.factory.AbstractCatalogableEntityModelFactory@785544b5}
  [PageTemplateModel] : {Object=com.nemesis.platform.core.factory.AbstractCatalogableEntityModelFactory@10421bb1}
  [ClassificationFeatureModel] : {Object=com.nemesis.platform.core.factory.AbstractCatalogableEntityModelFactory@604c6ff7}
  [CookiePolicyWidget] : {Object=com.nemesis.platform.core.factory.AbstractCatalogableEntityModelFactory@6d2baeea}
  [NavigationBarWidget] : {Object=com.nemesis.platform.core.factory.AbstractCatalogableEntityModelFactory@1285ef8c}
  [EmailPageModel] : {Object=com.nemesis.platform.core.factory.AbstractCatalogableEntityModelFactory@32058d9f}
  [ParagraphWidget] : {Object=com.nemesis.platform.core.factory.AbstractCatalogableEntityModelFactory@1fe7792e}
  [AbstractPageModel] : {Object=com.nemesis.platform.core.factory.AbstractCatalogableEntityModelFactory@41c98f1}
  [SuperBannerWidget] : {Object=com.nemesis.platform.core.factory.AbstractCatalogableEntityModelFactory@9baca85}
  [SimpleCarouselWidget] : {Object=com.nemesis.platform.core.factory.AbstractCatalogableEntityModelFactory@7fcc552}
  [InvoicePageModel] : {Object=com.nemesis.platform.core.factory.AbstractCatalogableEntityModelFactory@cf108f1}
  [ProjectVariantProductModel] : {Object=com.nemesis.platform.core.factory.AbstractCatalogableEntityModelFactory@4ed1a08}
  [BlogEntryModel] : {Object=com.nemesis.platform.core.factory.AbstractCatalogableEntityModelFactory@14687aa3}
  [DetailsPageModel] : {Object=com.nemesis.platform.core.factory.AbstractCatalogableEntityModelFactory@11119f7e}
  [VariantProductModel] : {Object=com.nemesis.platform.core.factory.AbstractCatalogableEntityModelFactory@2f1b4a04}
  [ProductModel] : {Object=com.nemesis.platform.core.factory.AbstractCatalogableEntityModelFactory@6a14e76c}
  [FooterWidget] : {Object=com.nemesis.platform.core.factory.AbstractCatalogableEntityModelFactory@4cf0a786}
  [StackExchangeQuestionsWidget] : {Object=com.nemesis.platform.core.factory.AbstractCatalogableEntityModelFactory@6afc8dea}
  [SocialWidget] : {Object=com.nemesis.platform.core.factory.AbstractCatalogableEntityModelFactory@bec4324}
  [MiniCartWidget] : {Object=com.nemesis.platform.core.factory.AbstractCatalogableEntityModelFactory@418ffd99}
  [WidgetModel] : {Object=com.nemesis.platform.core.factory.AbstractCatalogableEntityModelFactory@1d0ff121}
  [GooglemapWidget] : {Object=com.nemesis.platform.core.factory.AbstractCatalogableEntityModelFactory@1b1b4764}
  [ContentPageModel] : {Object=com.nemesis.platform.core.factory.AbstractCatalogableEntityModelFactory@76c1822d}
  [CmsNavigationNodeModel] : {Object=com.nemesis.platform.core.factory.AbstractCatalogableEntityModelFactory@13399b04}
  [WishlistWidget] : {Object=com.nemesis.platform.core.factory.AbstractCatalogableEntityModelFactory@18c73094}
  [ProductReferencesWidget] : {Object=com.nemesis.platform.core.factory.AbstractCatalogableEntityModelFactory@21538d0a}
-------------------------------------------------------------
Registered mappers: 41 (approximate size: 165,017.9 kB)
  [0] : GeneratedMapper<ProjectProductModel, ProjectProductModel> {usedConverters: [], usedMappers: [ma.glasnost.orika.impl.ReversedMapper@b4602b2], usedMapperFacades: [], usedTypes: [ProductMaterialModel] }
  [1] : GeneratedMapper<CookiePolicyWidget, CookiePolicyWidget> {usedConverters: [builtin:PassThroughConverter(Copy by reference:URL, URI, UUID, BigInteger, Locale, File, Inet4Address, Inet6Address, InetSocketAddress), PassThroughConverter(Copy by reference:ZonedDateTime, OffsetDateTime, Localized, AbstractEntityEnum, Enum<Enum>)], usedMappers: [ma.glasnost.orika.impl.ReversedMapper@5ab3f57a], usedMapperFacades: [], usedTypes: [Locale, LocalizedValue, CookiePolicyWidgetPositionDefinition] }
  [2] : GeneratedMapper<PriceModel, PriceModel> {usedConverters: [CustomConverter<Object, Object>], usedMappers: [], usedMapperFacades: [DefaultBoundMapperFacade<ProductModelDefinition, ProductModelDefinition>], usedTypes: [CurrencyModelDefinition] }
  [3] : GeneratedMapper<NavigationBarWidget, NavigationBarWidget> {usedConverters: [], usedMappers: [ma.glasnost.orika.impl.ReversedMapper@5f1d84], usedMapperFacades: [DefaultBoundMapperFacade<LinkWidgetDefinition, LinkWidgetDefinition>, DefaultBoundMapperFacade<CmsNavigationNodeModelDefinition, CmsNavigationNodeModelDefinition>], usedTypes: [] }
  [4] : GeneratedMapper<EmailPageModel, EmailPageModel> {usedConverters: [builtin:PassThroughConverter(Copy by reference:URL, URI, UUID, BigInteger, Locale, File, Inet4Address, Inet6Address, InetSocketAddress), PassThroughConverter(Copy by reference:ZonedDateTime, OffsetDateTime, Localized, AbstractEntityEnum, Enum<Enum>)], usedMappers: [ma.glasnost.orika.impl.ReversedMapper@6e607dc4], usedMapperFacades: [], usedTypes: [Locale, LocalizedValue] }
  [5] : GeneratedMapper<ParagraphWidget, ParagraphWidget> {usedConverters: [], usedMappers: [ma.glasnost.orika.impl.ReversedMapper@1319f350], usedMapperFacades: [], usedTypes: [] }
  [6] : GeneratedMapper<SelectorWidget, SelectorWidget> {usedConverters: [], usedMappers: [ma.glasnost.orika.impl.ReversedMapper@c7a0972], usedMapperFacades: [], usedTypes: [] }
  [7] : GeneratedMapper<SuperBannerWidget, SuperBannerWidget> {usedConverters: [builtin:PassThroughConverter(Copy by reference:URL, URI, UUID, BigInteger, Locale, File, Inet4Address, Inet6Address, InetSocketAddress), PassThroughConverter(Copy by reference:ZonedDateTime, OffsetDateTime, Localized, AbstractEntityEnum, Enum<Enum>)], usedMappers: [ma.glasnost.orika.impl.ReversedMapper@7f9ed547, ma.glasnost.orika.impl.ReversedMapper@3910c4ea], usedMapperFacades: [], usedTypes: [Locale, LocalizedLobValue, LinkWidgetDefinition] }
  [8] : GeneratedMapper<ContentSlotModel, ContentSlotModel> {usedConverters: [], usedMappers: [], usedMapperFacades: [DefaultBoundMapperFacade<AbstractPageModelDefinition, AbstractPageModelDefinition>, DefaultBoundMapperFacade<AbstractTemplateModelDefinition, AbstractTemplateModelDefinition>], usedTypes: [WidgetModelDefinition] }
  [9] : GeneratedMapper<SimpleCarouselWidget, SimpleCarouselWidget> {usedConverters: [], usedMappers: [ma.glasnost.orika.impl.ReversedMapper@52bb73b], usedMapperFacades: [], usedTypes: [WidgetModelDefinition] }
  [10] : GeneratedMapper<InvoicePageModel, InvoicePageModel> {usedConverters: [PassThroughConverter(Copy by reference:ZonedDateTime, OffsetDateTime, Localized, AbstractEntityEnum, Enum<Enum>)], usedMappers: [ma.glasnost.orika.impl.ReversedMapper@101d090d], usedMapperFacades: [], usedTypes: [OrientationDefinition] }
  [11] : GeneratedMapper<ProjectVariantProductModel, ProjectVariantProductModel> {usedConverters: [CustomConverter<Object, Object>], usedMappers: [ma.glasnost.orika.impl.ReversedMapper@56cdbe3d, ma.glasnost.orika.impl.ReversedMapper@1a81575b], usedMapperFacades: [], usedTypes: [MediaModel] }
  [12] : GeneratedMapper<DetailsPageModel, DetailsPageModel> {usedConverters: [], usedMappers: [ma.glasnost.orika.impl.ReversedMapper@5bc12203], usedMapperFacades: [], usedTypes: [] }
  [13] : GeneratedMapper<BlogEntryModel, BlogEntryModel> {usedConverters: [builtin:PassThroughConverter(Copy by reference:URL, URI, UUID, BigInteger, Locale, File, Inet4Address, Inet6Address, InetSocketAddress), PassThroughConverter(Copy by reference:ZonedDateTime, OffsetDateTime, Localized, AbstractEntityEnum, Enum<Enum>)], usedMappers: [], usedMapperFacades: [DefaultBoundMapperFacade<LocalDateTime, LocalDateTime>], usedTypes: [BlogCategoryModelDefinition, Locale, LocalizedLobValue, LocalizedValue] }
  [14] : GeneratedMapper<VoucherModel, VoucherModel> {usedConverters: [CustomConverter<Object, Object>], usedMappers: [ma.glasnost.orika.impl.ReversedMapper@2d205295], usedMapperFacades: [], usedTypes: [SiteModelDefinition] }
  [15] : GeneratedMapper<FooterWidget, FooterWidget> {usedConverters: [], usedMappers: [ma.glasnost.orika.impl.ReversedMapper@1750e99e], usedMapperFacades: [], usedTypes: [CmsNavigationNodeModelDefinition] }
  [16] : GeneratedMapper<LinkWidget, LinkWidget> {usedConverters: [CustomConverter<Object, Object>, builtin:PassThroughConverter(Copy by reference:URL, URI, UUID, BigInteger, Locale, File, Inet4Address, Inet6Address, InetSocketAddress), PassThroughConverter(Copy by reference:ZonedDateTime, OffsetDateTime, Localized, AbstractEntityEnum, Enum<Enum>)], usedMappers: [ma.glasnost.orika.impl.ReversedMapper@5bcef5bb], usedMapperFacades: [DefaultBoundMapperFacade<ContentPageModelDefinition, ContentPageModelDefinition>, DefaultBoundMapperFacade<ProductModelDefinition, ProductModelDefinition>], usedTypes: [CategoryModelDefinition, Locale, LocalizedValue, ProductModelDefinition] }
  [17] : GeneratedMapper<BlogCategoryModel, BlogCategoryModel> {usedConverters: [builtin:PassThroughConverter(Copy by reference:URL, URI, UUID, BigInteger, Locale, File, Inet4Address, Inet6Address, InetSocketAddress), PassThroughConverter(Copy by reference:ZonedDateTime, OffsetDateTime, Localized, AbstractEntityEnum, Enum<Enum>)], usedMappers: [], usedMapperFacades: [], usedTypes: [BlogEntryModelDefinition, Locale, LocalizedValue] }
  [18] : GeneratedMapper<StackExchangeQuestionsWidget, StackExchangeQuestionsWidget> {usedConverters: [], usedMappers: [ma.glasnost.orika.impl.ReversedMapper@71f1c94a], usedMapperFacades: [], usedTypes: [] }
  [19] : GeneratedMapper<SocialWidget, SocialWidget> {usedConverters: [], usedMappers: [ma.glasnost.orika.impl.ReversedMapper@360fa5b0], usedMapperFacades: [], usedTypes: [LinkWidgetDefinition] }
  [20] : GeneratedMapper<MiniCartWidget, MiniCartWidget> {usedConverters: [], usedMappers: [ma.glasnost.orika.impl.ReversedMapper@7b961cb9], usedMapperFacades: [], usedTypes: [] }
  [21] : GeneratedMapper<ListerPageModel, ListerPageModel> {usedConverters: [], usedMappers: [ma.glasnost.orika.impl.ReversedMapper@6f2a32ea], usedMapperFacades: [], usedTypes: [] }
  [22] : GeneratedMapper<CategoryListerWidget, CategoryListerWidget> {usedConverters: [], usedMappers: [ma.glasnost.orika.impl.ReversedMapper@1d7a6f0b], usedMapperFacades: [], usedTypes: [CategoryModelDefinition] }
  [23] : GeneratedMapper<GooglemapWidget, GooglemapWidget> {usedConverters: [PassThroughConverter(Copy by reference:ZonedDateTime, OffsetDateTime, Localized, AbstractEntityEnum, Enum<Enum>)], usedMappers: [ma.glasnost.orika.impl.ReversedMapper@56294d54], usedMapperFacades: [], usedTypes: [GooglemapTypeDefinition] }
  [24] : GeneratedMapper<ChatWidget, ChatWidget> {usedConverters: [], usedMappers: [ma.glasnost.orika.impl.ReversedMapper@6480656a], usedMapperFacades: [], usedTypes: [] }
  [25] : GeneratedMapper<ContentPageModel, ContentPageModel> {usedConverters: [], usedMappers: [ma.glasnost.orika.impl.ReversedMapper@7fc459c9], usedMapperFacades: [], usedTypes: [] }
  [26] : GeneratedMapper<StockLevelModel, StockLevelModel> {usedConverters: [PassThroughConverter(Copy by reference:ZonedDateTime, OffsetDateTime, Localized, AbstractEntityEnum, Enum<Enum>)], usedMappers: [], usedMapperFacades: [DefaultBoundMapperFacade<ProductModelDefinition, ProductModelDefinition>], usedTypes: [InStockStatusDefinition] }
  [27] : GeneratedMapper<CmsNavigationNodeModel, CmsNavigationNodeModel> {usedConverters: [builtin:PassThroughConverter(Copy by reference:URL, URI, UUID, BigInteger, Locale, File, Inet4Address, Inet6Address, InetSocketAddress), PassThroughConverter(Copy by reference:ZonedDateTime, OffsetDateTime, Localized, AbstractEntityEnum, Enum<Enum>)], usedMappers: [], usedMapperFacades: [], usedTypes: [CmsNavigationNodeModelDefinition, AbstractFilterModelDefinition, LinkWidgetDefinition, ParagraphWidgetDefinition, Locale, LocalizedValue] }
  [28] : GeneratedMapper<ProductCarouselWidget, ProductCarouselWidget> {usedConverters: [], usedMappers: [ma.glasnost.orika.impl.ReversedMapper@64478bd2], usedMapperFacades: [], usedTypes: [CategoryModelDefinition, ProductModelDefinition] }
  [29] : GeneratedMapper<WishlistWidget, WishlistWidget> {usedConverters: [], usedMappers: [ma.glasnost.orika.impl.ReversedMapper@f610efe], usedMapperFacades: [], usedTypes: [] }
  [30] : GeneratedMapper<TaxModel, TaxModel> {usedConverters: [CustomConverter<Object, Object>], usedMappers: [], usedMapperFacades: [DefaultBoundMapperFacade<ProductModelDefinition, ProductModelDefinition>], usedTypes: [CurrencyModelDefinition] }
  [31] : GeneratedMapper<PageTemplateModel, PageTemplateModel> {usedConverters: [], usedMappers: [ma.glasnost.orika.impl.ReversedMapper@314edb78], usedMapperFacades: [], usedTypes: [] }
  [32] : GeneratedMapper<ProductReferencesWidget, ProductReferencesWidget> {usedConverters: [], usedMappers: [ma.glasnost.orika.impl.ReversedMapper@49992ebc], usedMapperFacades: [], usedTypes: [] }
  [33] : GeneratedMapper<ClassificationFeatureModel, ClassificationFeatureModel> {usedConverters: [CustomConverter<Object, Object>, builtin:PassThroughConverter(Copy by reference:URL, URI, UUID, BigInteger, Locale, File, Inet4Address, Inet6Address, InetSocketAddress), PassThroughConverter(Copy by reference:ZonedDateTime, OffsetDateTime, Localized, AbstractEntityEnum, Enum<Enum>)], usedMappers: [], usedMapperFacades: [], usedTypes: [ClassificationCategoryModelDefinition, Locale, LocalizedValue] }
  [34] : GeneratedMapper<SimpleBannerWidget, SimpleBannerWidget> {usedConverters: [CustomConverter<Object, Object>], usedMappers: [ma.glasnost.orika.impl.ReversedMapper@64bb09c], usedMapperFacades: [], usedTypes: [MediaModelDefinition] }
  [35] : GeneratedMapper<VariantProductModel, VariantProductModel> {usedConverters: [], usedMappers: [ma.glasnost.orika.impl.ReversedMapper@5b3c23ab], usedMapperFacades: [DefaultBoundMapperFacade<ProductModelDefinition, ProductModelDefinition>], usedTypes: [] }
  [36] : GeneratedMapper<DiscountModel, DiscountModel> {usedConverters: [CustomConverter<Object, Object>], usedMappers: [], usedMapperFacades: [DefaultBoundMapperFacade<ProductModelDefinition, ProductModelDefinition>], usedTypes: [CurrencyModelDefinition, PromotionModelDefinition] }
  [37] : GeneratedMapper<AbstractPageModel, AbstractPageModel> {usedConverters: [CustomConverter<Object, Object>, builtin:PassThroughConverter(Copy by reference:URL, URI, UUID, BigInteger, Locale, File, Inet4Address, Inet6Address, InetSocketAddress), PassThroughConverter(Copy by reference:ZonedDateTime, OffsetDateTime, Localized, AbstractEntityEnum, Enum<Enum>)], usedMappers: [], usedMapperFacades: [DefaultBoundMapperFacade<AbstractTemplateModelDefinition, AbstractTemplateModelDefinition>], usedTypes: [MediaModelDefinition, ContentSlotModelDefinition, Locale, LocalizedValue] }
  [38] : GeneratedMapper<AbstractTemplateModel, AbstractTemplateModel> {usedConverters: [], usedMappers: [], usedMapperFacades: [], usedTypes: [ContentSlotModelDefinition] }
  [39] : GeneratedMapper<WidgetModel, WidgetModel> {usedConverters: [builtin:PassThroughConverter(Copy by reference:URL, URI, UUID, BigInteger, Locale, File, Inet4Address, Inet6Address, InetSocketAddress), PassThroughConverter(Copy by reference:ZonedDateTime, OffsetDateTime, Localized, AbstractEntityEnum, Enum<Enum>)], usedMappers: [], usedMapperFacades: [DefaultBoundMapperFacade<LocalDateTime, LocalDateTime>], usedTypes: [Locale, LocalizedLobValue, AbstractFilterModelDefinition, LocalizedValue] }
  [40] : GeneratedMapper<ProductModel, ProductModel> {usedConverters: [PassThroughConverter(Copy by reference:ZonedDateTime, OffsetDateTime, Localized, AbstractEntityEnum, Enum<Enum>), CustomConverter<Object, Object>, builtin:PassThroughConverter(Copy by reference:URL, URI, UUID, BigInteger, Locale, File, Inet4Address, Inet6Address, InetSocketAddress)], usedMappers: [], usedMapperFacades: [DefaultBoundMapperFacade<LocalDateTime, LocalDateTime>], usedTypes: [ProductApprovalStatusDefinition, UnitModelDefinition, Locale, LocalizedLobValue, DiscountModelDefinition, MediaContainerModelDefinition, LocalizedValue, MediaModelDefinition, PriceModelDefinition, ProductReferenceModelDefinition, CustomerReviewModelDefinition, StockLevelModelDefinition, CategoryModelDefinition, TaxModelDefinition, VariantTypeModelDefinition, VariantProductModelDefinition] }
-------------------------------------------------------------
Registered concrete types: 186 (approximate size: 6,156.8 kB)
  [interface com.nemesis.platform.module.widget.chat.core.definition.ChatWidgetDefinition] : ChatWidget
  [interface com.nemesis.platform.module.widget.social.core.definition.SocialWidgetDefinition] : SocialWidget
  [interface com.nemesis.platform.module.commerce.core.definition.price.PriceModelDefinition] : PriceModel
  [interface com.nemesis.platform.core.definition.user.UserModelDefinition] : UserModel
  [interface com.nemesis.platform.module.search.core.definition.SearchIndexConfigModelDefinition] : SearchIndexConfigModel
  [interface com.nemesis.platform.module.commerce.core.definition.catalog.KeywordModelDefinition] : KeywordModel
  [interface com.nemesis.platform.module.commerce.core.definition.order.OrderModelDefinition] : OrderModel
  [interface com.nemesis.platform.module.classification.core.definition.ClassificationSystemVersionModelDefinition] : ClassificationSystemVersionModel
  [interface com.nemesis.platform.core.definition.catalog.CatalogModelDefinition] : CatalogModel
  [interface com.nemesis.platform.module.social.core.definition.SocialCustomerModelDefinition] : CustomerModel
  [interface com.nemesis.platform.core.definition.media.MediaModelDefinition] : MediaModel
  [interface com.nemesis.platform.core.definition.cms.SiteModelDefinition] : SiteModel
  [interface com.nemesis.platform.module.cms.core.definition.ContentSlotModelDefinition] : ContentSlotModel
  [interface com.nemesis.platform.module.cms.core.definition.AbstractCmsEntityModelDefinition] : WidgetModel
  [interface com.nemesis.platform.module.classification.core.definition.ClassificationSystemModelDefinition] : ClassificationSystemModel
  [interface com.nemesis.platform.module.widget.carousel.core.definition.ProductCarouselWidgetDefinition] : ProductCarouselWidget
  [interface com.nemesis.platform.module.cms.core.definition.WidgetModelDefinition] : WidgetModel
  [interface com.nemesis.platform.module.promotion.core.definition.product.ProductPerfectPartnerPromotionModelDefinition] : ProductPerfectPartnerPromotionModel
  [interface com.nemesis.platform.module.storelocator.core.definition.WeekdayWorkingModelDefinition] : WeekdayWorkingModel
  [interface com.nemesis.platform.module.promotion.core.definition.product.ProductBOGOFPromotionModelDefinition] : ProductBOGOFPromotionModel
  [interface com.nemesis.platform.module.widget.stackexchangequestions.core.definition.StackExchangeQuestionsWidgetDefinition] : StackExchangeQuestionsWidget
  [interface com.nemesis.platform.module.commerce.core.definition.catalog.ProductReferenceModelDefinition] : ProductReferenceModel
  [interface com.nemesis.platform.module.cms.core.definition.AbstractTemplateModelDefinition] : AbstractTemplateModel
  [interface com.nemesis.platform.module.voucher.core.definition.VoucherModelDefinition] : VoucherModel
  [interface com.nemesis.platform.module.widget.footer.core.definition.FooterWidgetDefinition] : FooterWidget
  [interface com.nemesis.platform.core.definition.entity.AbstractNameableEntityModelDefinition] : ProductModel
  [interface com.nemesis.platform.module.widget.selector.core.definition.SelectorWidgetDefinition] : SelectorWidget
  [interface com.nemesis.platform.module.storelocator.core.definition.WorkingDayModelDefinition] : WorkingDayModel
  [interface com.nemesis.platform.module.commerce.core.definition.order.ReturnRequestModelDefinition] : ReturnRequestModel
  [interface com.nemesis.platform.module.commerce.core.definition.order.DeliveryModeModelDefinition] : DeliveryModeModel
  [interface com.nemesis.platform.module.search.core.definition.SearchPageRedirectModelDefinition] : SearchPageRedirectModel
  [interface com.nemesis.platform.module.promotion.core.definition.PromotionGroupModelDefinition] : PromotionGroupModel
  [interface com.nemesis.platform.core.definition.i18n.RegionModelDefinition] : RegionModel
  [interface com.nemesis.platform.core.definition.media.MediaContainerModelDefinition] : MediaContainerModel
  [interface com.nemesis.platform.module.blog.core.definition.BlogCategoryModelDefinition] : BlogCategoryModel
  [interface com.nemesis.platform.module.widget.googlemap.core.definition.GooglemapWidgetDefinition] : GooglemapWidget
  [interface com.nemesis.platform.core.definition.user.EmployeeModelDefinition] : EmployeeModel
  [interface com.nemesis.platform.module.widget.banner.core.definition.SimpleBannerWidgetDefinition] : SimpleBannerWidget
  [interface com.nemesis.platform.core.definition.i18n.CountryModelDefinition] : CountryModel
  [interface com.nemesis.platform.core.definition.batch.BatchJobExecutionParamsModelDefinition] : BatchJobExecutionParamsModel
  [interface com.nemesis.platform.core.definition.batch.BatchJobExecutionModelDefinition] : BatchJobExecutionModel
  [interface java.util.Set] : LinkedHashSet<Object>
  [interface com.nemesis.platform.module.search.core.definition.facet.SearchTermFacetModelDefinition] : SearchTermFacetModel
  [interface com.nemesis.platform.module.storelocator.core.definition.OpeningScheduleModelDefinition] : OpeningScheduleModel
  [interface com.nemesis.platform.module.sitemap.core.definition.SitemapConfigModelDefinition] : SitemapConfigModel
  [interface com.nemesis.platform.core.definition.batch.BatchJobExecutionContextModelDefinition] : BatchJobExecutionContextModel
  [interface com.nemesis.platform.module.promotion.core.definition.product.ProductOneToOnePerfectPartnerBundlePromotionModelDefinition] : ProductOneToOnePerfectPartnerBundlePromotionModel
  [interface com.nemesis.platform.module.storelocator.core.definition.StorefinderConfigurationModelDefinition] : StorefinderConfigurationModel
  [interface com.nemesis.platform.module.commerce.core.definition.order.CartModelDefinition] : CartModel
  [interface com.nemesis.platform.module.customerreview.core.definition.CustomerReviewModelDefinition] : CustomerReviewModel
  [interface com.nemesis.platform.core.definition.settings.SocialConfigurationModelDefinition] : SocialConfigurationModel
  [interface com.nemesis.platform.core.definition.location.PointOfServiceModelDefinition] : PointOfServiceModel
  [interface com.nemesis.platform.module.commerce.core.definition.catalog.ProductModelDefinition] : ProductModel
  [interface com.nemesis.platform.core.definition.batch.BatchStepExecutionModelDefinition] : BatchStepExecutionModel
  [interface com.nemesis.platform.module.commerce.core.definition.order.PaymentInfoModelDefinition] : PaymentInfoModel
  [interface com.nemesis.platform.core.definition.batch.CronjobModelDefinition] : CronjobModel
  [interface com.nemesis.platform.core.definition.filter.PrincipalInUserGroupFilterModelDefinition] : PrincipalInUserGroupFilterModel
  [interface com.nemesis.platform.module.search.core.definition.facet.SearchFacetModelDefinition] : SearchFacetModel
  [interface com.nemesis.platform.module.search.core.definition.facet.SearchTextFacetModelDefinition] : SearchTextFacetModel
  [interface com.nemesis.platform.module.promotion.core.definition.product.ProductPercentageDiscountPromotionModelDefinition] : ProductPercentageDiscountPromotionModel
  [interface com.nemesis.platform.core.definition.filter.AbstractFilterModelDefinition] : AbstractFilterModel
  [interface com.nemesis.platform.module.commerce.core.definition.order.CreditCardPaymentInfoModelDefinition] : CreditCardPaymentInfoModel
  [interface com.nemesis.platform.module.promotion.core.definition.product.ProductBundlePromotionModelDefinition] : ProductBundlePromotionModel
  [interface com.nemesis.platform.module.commerce.core.definition.catalog.VariantProductModelDefinition] : VariantProductModel
  [interface com.nemesis.platform.module.widget.navigation.core.definition.CmsNavigationNodeModelDefinition] : CmsNavigationNodeModel
  [interface com.nemesis.platform.module.search.core.definition.facet.NumberFacetModelDefinition] : NumberFacetModel
  [interface com.nemesis.platform.module.commerce.core.definition.catalog.VariantTypeModelDefinition] : VariantTypeModel
  [interface com.nemesis.platform.module.cms.core.definition.SiteThemeModelDefinition] : SiteThemeModel
  [interface com.nemesis.platform.module.commerce.core.definition.cms.CommerceSiteModelDefinition] : SiteModel
  [interface com.nemesis.platform.module.cms.core.definition.ContentPageModelDefinition] : ContentPageModel
  [interface com.nemesis.platform.core.definition.marketing.NewsletterSubscriberModelDefinition] : NewsletterSubscriberModel
  [interface com.nemesis.platform.core.definition.filter.CmsUiExperienceFilterModelDefinition] : CmsUiExperienceFilterModel
  [interface com.nemesis.platform.module.promotion.core.definition.order.OrderThresholdFixedDiscountPromotionModelDefinition] : OrderThresholdFixedDiscountPromotionModel
  [interface com.nemesis.platform.module.commerce.core.definition.catalog.StockLevelModelDefinition] : StockLevelModel
  [interface com.nemesis.platform.module.commerce.core.definition.price.DiscountModelDefinition] : DiscountModel
  [interface com.nemesis.platform.module.classification.core.definition.ClassificationCategoryModelDefinition] : ClassificationCategoryModel
  [interface com.nemesis.platform.module.sitemap.core.definition.SitemapPageModelDefinition] : SitemapPageModel
  [interface com.nemesis.platform.module.search.core.definition.facet.DiapasonRangeFacetModelDefinition] : DiapasonRangeFacetModel
  [interface com.nemesis.platform.module.search.core.definition.facet.SliderFacetModelDefinition] : SliderFacetModel
  [interface com.nemesis.platform.core.definition.i18n.LocaleModelDefinition] : LocaleModel
  [interface com.nemesis.platform.module.promotion.core.definition.PromotionModelDefinition] : PromotionModel
  [interface com.nemesis.platform.module.invoice.core.definition.InvoiceableSiteModelDefinition] : SiteModel
  [interface java.util.Map$Entry] : MapEntry<Object, Object>
  [interface com.nemesis.platform.core.definition.catalog.CategoryModelDefinition] : CategoryModel
  [interface com.nemesis.platform.core.definition.user.AddressModelDefinition] : AddressModel
  [interface com.nemesis.platform.module.commerce.core.definition.order.TerritoryModelDefinition] : TerritoryModel
  [interface com.nemesis.platform.module.commerce.core.definition.order.PaymentTransactionModelDefinition] : PaymentTransactionModel
  [interface com.nemesis.platform.module.commerce.core.definition.price.TaxModelDefinition] : TaxModel
  [interface com.nemesis.platform.module.promotion.core.definition.order.PromotionableAbstractOrderEntryModelDefinition] : AbstractOrderEntryModel
  [interface com.nemesis.platform.module.barcode.core.definition.BarcodeMediaModelDefinition] : BarcodeMediaModel
  [interface com.nemesis.platform.module.invoice.core.definition.InvoicePageModelDefinition] : InvoicePageModel
  [interface com.nemesis.platform.module.promotion.core.definition.PromotionableSiteModelDefinition] : SiteModel
  [interface com.nemesis.platform.module.storelocator.core.definition.StoreLocatorPointOfServiceModelDefinition] : PointOfServiceModel
  [interface com.nemesis.platform.module.cms.core.definition.ContentCatalogModelDefinition] : ContentCatalogModel
  [interface com.nemesis.platform.module.widget.carousel.core.definition.SimpleCarouselWidgetDefinition] : SimpleCarouselWidget
  [interface com.nemesis.platform.core.definition.user.PrincipalModelDefinition] : PrincipalModel
  [interface com.nemesis.platform.module.search.core.definition.SearchFacetConfigModelDefinition] : SearchFacetConfigModel
  [interface com.nemesis.platform.module.promotion.core.definition.PromotionResultModelDefinition] : PromotionResultModel
  [interface com.nemesis.platform.module.search.core.definition.facet.EntityFacetModelDefinition] : EntityFacetModel
  [interface com.nemesis.platform.module.commerce.core.definition.location.WarehouseModelDefinition] : WarehouseModel
  [interface com.nemesis.platform.module.promotion.core.definition.order.OrderThresholdPerfectPartnerPromotionModelDefinition] : OrderThresholdPerfectPartnerPromotionModel
  [interface com.nemesis.platform.module.promotion.core.definition.price.PromotionableDiscountModelDefinition] : DiscountModel
  [interface com.nemesis.platform.core.definition.media.MediaFolderModelDefinition] : MediaFolderModel
  [interface com.nemesis.platform.module.cms.core.definition.EmailPageModelDefinition] : EmailPageModel
  [interface com.nemesis.platform.module.search.core.definition.SearchIndexedPropertyModelDefinition] : SearchIndexedPropertyModel
  [interface com.nemesis.platform.module.commerce.core.definition.order.OrderEntryModelDefinition] : OrderEntryModel
  [interface com.nemesis.platform.module.cms.core.definition.DetailsPageModelDefinition] : DetailsPageModel
  [interface com.nemesis.platform.module.widget.productreferences.core.definition.ProductReferencesWidgetDefinition] : ProductReferencesWidget
  [interface com.nemesis.platform.module.commerce.core.definition.order.AbstractOrderEntryModelDefinition] : AbstractOrderEntryModel
  [interface com.nemesis.platform.module.ruleservices.core.definition.RuleModelDefinition] : RuleModel
  [interface com.nemesis.platform.module.promotion.core.definition.order.OrderThresholdFreeVoucherPromotionModelDefinition] : OrderThresholdFreeVoucherPromotionModel
  [interface com.nemesis.platform.module.voucher.core.definition.VoucherableAbstractOrderModelDefinition] : AbstractOrderModel
  [interface com.nemesis.platform.module.widget.categorylister.core.definition.CategoryListerWidgetDefinition] : CategoryListerWidget
  [interface com.nemesis.platform.module.commerce.core.definition.i18n.CurrencyModelDefinition] : CurrencyModel
  [interface com.nemesis.platform.module.commerce.core.definition.order.TerritoryDeliveryModeModelDefinition] : TerritoryDeliveryModeModel
  [interface com.nemesis.platform.module.commerce.core.definition.catalog.UnitModelDefinition] : UnitModel
  [interface com.nemesis.platform.module.cms.core.definition.ListerPageModelDefinition] : ListerPageModel
  [interface java.util.Map] : LinkedHashMap<Object, Object>
  [interface com.nemesis.platform.module.commerce.core.definition.order.TerritoryDeliveryModeValueModelDefinition] : TerritoryDeliveryModeValueModel
  [interface com.nemesis.platform.module.widget.wishlist.core.definition.WishlistWidgetDefinition] : WishlistWidget
  [interface com.nemesis.platform.module.cms.core.definition.AbstractPageModelDefinition] : AbstractPageModel
  [interface com.nemesis.platform.module.blog.core.definition.BlogEntryModelDefinition] : BlogEntryModel
  [interface com.nemesis.platform.core.definition.entity.AbstractActivatableEntityModelDefinition] : ContentSlotModel
  [interface com.nemesis.platform.module.promotion.core.definition.ProductPromotionModelDefinition] : ProductPromotionModel
  [interface com.nemesis.platform.core.definition.entity.AbstractFilteredEntityModelDefinition] : PromotionModel
  [interface com.nemesis.platform.core.definition.entity.AbstractDescriptionableEntityModelDefinition] : ProductModel
  [interface com.nemesis.platform.module.search.core.definition.SearchKeywordRedirectModelDefinition] : SearchKeywordRedirectModel
  [interface com.nemesis.platform.module.promotion.core.definition.PromotionPriceRowModelDefinition] : PromotionPriceRowModel
  [interface com.nemesis.platform.module.promotion.core.definition.order.PromotionDeliveryModeModelDefinition] : PromotionDeliveryModeModel
  [interface com.nemesis.platform.module.customerreview.core.definition.ReviewedProductModelDefinition] : ProductModel
  [interface com.nemesis.platform.core.definition.user.TitleModelDefinition] : TitleModel
  [interface com.nemesis.platform.module.commerce.core.definition.order.PaymentModeModelDefinition] : PaymentModeModel
  [interface com.nemesis.platform.core.definition.batch.BatchStepExecutionContextModelDefinition] : BatchStepExecutionContextModel
  [interface com.nemesis.platform.module.commerce.core.definition.order.AbstractPurchasableEntityModelDefinition] : AbstractOrderEntryModel
  [interface com.nemesis.platform.core.definition.entity.AbstractCatalogableEntityModelDefinition] : DiscountModel
  [interface com.nemesis.platform.module.deeplink.core.definition.DeeplinkUrlRuleModelDefinition] : DeeplinkUrlRuleModel
  [interface com.nemesis.platform.module.guarantee.core.definition.GuaranteeModelDefinition] : GuaranteeModel
  [interface com.nemesis.platform.core.definition.user.UserGroupModelDefinition] : UserGroupModel
  [interface com.nemesis.platform.module.wishlist.core.definition.WishlistModelDefinition] : WishlistModel
  [interface com.nemesis.platform.module.search.core.definition.SearchIndexedTypeModelDefinition] : SearchIndexedTypeModel
  [interface com.nemesis.platform.module.social.core.definition.SocialConnectionModelDefinition] : SocialConnectionModel
  [interface com.nemesis.platform.core.definition.entity.AbstractModifiableEntityModelDefinition] : AbstractModifiableEntityModel
  [interface com.nemesis.platform.module.cms.core.definition.PageTemplateModelDefinition] : PageTemplateModel
  [interface com.nemesis.platform.core.definition.filter.CustomerOfTypeFilterModelDefinition] : CustomerOfTypeFilterModel
  [interface com.nemesis.platform.module.voucher.core.definition.VoucherInvalidationModelDefinition] : VoucherInvalidationModel
  [interface com.nemesis.platform.module.commerce.core.definition.order.AdvancePaymentInfoModelDefinition] : AdvancePaymentInfoModel
  [interface com.nemesis.platform.module.cms.core.definition.CmsSiteModelDefinition] : SiteModel
  [interface java.util.List] : ArrayList<Object>
  [interface java.util.Collection] : ArrayList<Object>
  [interface com.nemesis.platform.module.commerce.core.definition.user.CommerceCustomerModelDefinition] : CustomerModel
  [interface com.nemesis.platform.core.definition.batch.BatchJobInstanceModelDefinition] : BatchJobInstanceModel
  [interface com.nemesis.platform.module.commerce.core.definition.price.PackagingModelDefinition] : PackagingModel
  [interface com.nemesis.platform.module.commerce.core.definition.catalog.VariantAttributeDescriptorModelDefinition] : VariantAttributeDescriptorModel
  [interface com.nemesis.platform.module.widget.minicart.core.definition.MiniCartWidgetDefinition] : MiniCartWidget
  [interface com.nemesis.platform.module.widget.banner.core.definition.SuperBannerWidgetDefinition] : SuperBannerWidget
  [interface com.nemesis.platform.core.definition.media.MediaFormatModelDefinition] : MediaFormatModel
  [interface com.nemesis.platform.module.promotion.core.definition.order.OrderThresholdFreeGiftPromotionModelDefinition] : OrderThresholdFreeGiftPromotionModel
  [interface com.nemesis.platform.module.social.core.definition.SocialEmployeeModelDefinition] : EmployeeModel
  [interface com.nemesis.platform.module.search.core.definition.facet.RangeFacetModelDefinition] : RangeFacetModel
  [interface com.nemesis.platform.module.sitemap.core.definition.SitemapSiteModelDefinition] : SiteModel
  [interface com.nemesis.platform.module.widget.link.core.definition.LinkWidgetDefinition] : LinkWidget
  [interface com.nemesis.platform.module.commerce.core.definition.order.CartEntryModelDefinition] : CartEntryModel
  [interface com.nemesis.platform.core.definition.settings.EmailConfigurationModelDefinition] : EmailConfigurationModel
  [interface com.nemesis.platform.core.definition.entity.modification.EntityModificationModelDefinition] : EntityModificationModel
  [interface com.nemesis.platform.module.social.core.definition.SocialSiteModelDefinition] : SiteModel
  [interface com.nemesis.platform.core.definition.catalog.CatalogVersionModelDefinition] : CatalogVersionModel
  [interface com.nemesis.platform.module.promotion.core.definition.product.ProductMultibuyPromotionModelDefinition] : ProductMultibuyPromotionModel
  [interface com.nemesis.platform.module.promotion.core.definition.order.OrderThresholdChangeDeliveryModePromotionModelDefinition] : OrderThresholdChangeDeliveryModePromotionModel
  [interface com.nemesis.platform.module.widget.paragraph.core.definition.ParagraphWidgetDefinition] : ParagraphWidget
  [interface com.nemesis.platform.core.definition.user.CustomerModelDefinition] : CustomerModel
  [interface com.nemesis.platform.module.widget.navigation.core.definition.NavigationBarWidgetDefinition] : NavigationBarWidget
  [interface com.nemesis.platform.module.promotion.core.definition.product.ProductSteppedMultibuyPromotionModelDefinition] : ProductSteppedMultibuyPromotionModel
  [interface com.nemesis.platform.module.commerce.core.definition.order.InvoiceModelDefinition] : InvoiceModel
  [interface com.nemesis.platform.module.promotion.core.definition.OrderPromotionModelDefinition] : OrderPromotionModel
  [interface com.nemesis.platform.module.promotion.core.definition.PromotionOrderEntryConsumedModelDefinition] : PromotionOrderEntryConsumedModel
  [interface com.nemesis.platform.module.promotion.core.definition.product.ProductPerfectPartnerBundlePromotionModelDefinition] : ProductPerfectPartnerBundlePromotionModel
  [interface com.nemesis.platform.module.search.core.definition.SearchConfigModelDefinition] : SearchConfigModel
  [interface com.nemesis.platform.module.deeplink.core.definition.DeeplinkUrlModelDefinition] : DeeplinkUrlModel
  [interface com.nemesis.platform.module.commerce.core.definition.order.AbstractOrderModelDefinition] : AbstractOrderModel
  [interface com.nemesis.platform.module.promotion.core.definition.product.ProductFixedPricePromotionModelDefinition] : ProductFixedPricePromotionModel
  [interface com.nemesis.platform.core.definition.media.MediaWatermarkModelDefinition] : MediaWatermarkModel
  [interface com.nemesis.platform.module.commerce.core.definition.order.PaymentTransactionEntryModelDefinition] : PaymentTransactionEntryModel
  [interface com.nemesis.platform.module.classification.core.definition.ClassificationFeatureModelDefinition] : ClassificationFeatureModel
  [interface com.nemesis.platform.module.wishlist.core.definition.WishlistEntryModelDefinition] : WishlistEntryModel
  [interface com.nemesis.platform.module.widget.cookiepolicy.core.definition.CookiePolicyWidgetDefinition] : CookiePolicyWidget
  [interface com.nemesis.platform.module.search.core.definition.SearchServerConfigModelDefinition] : SearchServerConfigModel
-------------------------------------------------------------
Resolved strategies: 1 (approximate size: 165,020.3 kB)
{source: SocialWidget, dest: SocialWidget, in-place:false}: InstantiateAndUseCustomMapperStrategy<SocialWidget, SocialWidget> {customMapper: GeneratedMapper<SocialWidget, SocialWidget> {usedConverters: [], usedMappers: [ma.glasnost.orika.impl.ReversedMapper@360fa5b0], usedMapperFacades: [], usedTypes: [LinkWidgetDefinition] }, unenhancer: ma.glasnost.orika.unenhance.BaseUnenhancer@35e5f050, objectFactory: com.nemesis.platform.core.factory.AbstractCatalogableEntityModelFactory@bec4324}
-------------------------------------------------------------
Unenhance strategy: ma.glasnost.orika.unenhance.BaseUnenhancer@35e5f050
-----end dump of current state-------------------------------
    at ma.glasnost.orika.impl.ExceptionUtility.newMappingException(ExceptionUtility.java:55)
    at ma.glasnost.orika.impl.MapperFacadeImpl.map(MapperFacadeImpl.java:750)
    at ma.glasnost.orika.impl.MapperFacadeImpl.map(MapperFacadeImpl.java:719)
    at ma.glasnost.orika.impl.ConfigurableMapper.map(ConfigurableMapper.java:158)
    at com.nemesis.platform.core.batch.processor.DefaultSyncEntityProcessor.process(DefaultSyncEntityProcessor.java:47)
    at com.nemesis.platform.core.batch.processor.DefaultSyncEntityProcessor.process(DefaultSyncEntityProcessor.java:28)
    at org.springframework.batch.core.step.item.SimpleChunkProcessor.doProcess(SimpleChunkProcessor.java:126)
    at org.springframework.batch.core.step.item.SimpleChunkProcessor.transform(SimpleChunkProcessor.java:293)
    at org.springframework.batch.core.step.item.SimpleChunkProcessor.process(SimpleChunkProcessor.java:192)
    at org.springframework.batch.core.step.item.ChunkOrientedTasklet.execute(ChunkOrientedTasklet.java:75)
    at org.springframework.batch.core.step.tasklet.TaskletStep$ChunkTransactionCallback.doInTransaction(TaskletStep.java:406)
    at org.springframework.batch.core.step.tasklet.TaskletStep$ChunkTransactionCallback.doInTransaction(TaskletStep.java:330)
    at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:133)
    at org.springframework.batch.core.step.tasklet.TaskletStep$2.doInChunkContext(TaskletStep.java:271)
    at org.springframework.batch.core.scope.context.StepContextRepeatCallback.doInIteration(StepContextRepeatCallback.java:77)
    at org.springframework.batch.repeat.support.RepeatTemplate.getNextResult(RepeatTemplate.java:368)
    at org.springframework.batch.repeat.support.RepeatTemplate.executeInternal(RepeatTemplate.java:215)
    at org.springframework.batch.repeat.support.RepeatTemplate.iterate(RepeatTemplate.java:144)
    at org.springframework.batch.core.step.tasklet.TaskletStep.doExecute(TaskletStep.java:257)
    at org.springframework.batch.core.step.AbstractStep.execute(AbstractStep.java:198)
    at org.springframework.batch.core.job.SimpleStepHandler.handleStep(SimpleStepHandler.java:148)
    at org.springframework.batch.core.job.AbstractJob.handleStep(AbstractJob.java:386)
    at org.springframework.batch.core.job.SimpleJob.doExecute(SimpleJob.java:135)
    at org.springframework.batch.core.job.AbstractJob.execute(AbstractJob.java:304)
    at org.springframework.batch.core.launch.support.SimpleJobLauncher$1.run(SimpleJobLauncher.java:135)
    at org.springframework.core.task.SyncTaskExecutor.execute(SyncTaskExecutor.java:50)
    at org.springframework.batch.core.launch.support.SimpleJobLauncher.run(SimpleJobLauncher.java:128)
    at com.nemesis.platform.core.service.catalog.impl.BatchCatalogServiceImpl.synchronizeCatalogAsynchronously(BatchCatalogServiceImpl.java:65)
    at com.nemesis.platform.core.service.catalog.impl.AbstractCatalogServiceImpl.synchronizeAllCatalogs(AbstractCatalogServiceImpl.java:48)
    at com.nemesis.platform.core.service.catalog.impl.BatchCatalogServiceImpl.synchronizeAllCatalogs(BatchCatalogServiceImpl.java:79)
    at com.nemesis.platform.core.service.platform.impl.PlatformServiceImpl.initializeDatabase(PlatformServiceImpl.java:191)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:317)
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:201)
    at com.sun.proxy.$Proxy151.initializeDatabase(Unknown Source)
    at com.nemesis.maven.plugin.platform.init.InitPlatformDBMojo.doExecute(InitPlatformDBMojo.java:33)
    at com.nemesis.maven.plugin.mojo.AbstractNemesisPlatformMojo.execute(AbstractNemesisPlatformMojo.java:95)
    at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo(DefaultBuildPluginManager.java:132)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:208)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:153)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:145)
    at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:116)
    at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:80)
    at org.apache.maven.lifecycle.internal.builder.singlethreaded.SingleThreadedBuilder.build(SingleThreadedBuilder.java:51)
    at org.apache.maven.lifecycle.internal.LifecycleStarter.execute(LifecycleStarter.java:120)
    at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:355)
    at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:155)
    at org.apache.maven.cli.MavenCli.execute(MavenCli.java:584)
    at org.apache.maven.cli.MavenCli.doMain(MavenCli.java:216)
    at org.apache.maven.cli.MavenCli.main(MavenCli.java:160)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced(Launcher.java:289)
    at org.codehaus.plexus.classworlds.launcher.Launcher.launch(Launcher.java:229)
    at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode(Launcher.java:415)
    at org.codehaus.plexus.classworlds.launcher.Launcher.main(Launcher.java:356)
Caused by: java.lang.NullPointerException
    at ma.glasnost.orika.generated.Orika_WidgetModel_WidgetModel_Mapper1410991139170$28.mapBtoA(Orika_WidgetModel_WidgetModel_Mapper1410991139170$28.java)
    at ma.glasnost.orika.impl.ReversedMapper.mapAtoB(ReversedMapper.java:65)
    at ma.glasnost.orika.impl.GeneratedMapperBase.mapAtoB(GeneratedMapperBase.java:128)
    at ma.glasnost.orika.generated.Orika_SocialWidget_SocialWidget_Mapper1410979209945$25.mapAtoB(Orika_SocialWidget_SocialWidget_Mapper1410979209945$25.java)
    at ma.glasnost.orika.impl.mapping.strategy.UseCustomMapperStrategy.map(UseCustomMapperStrategy.java:67)
    at ma.glasnost.orika.impl.MapperFacadeImpl.map(MapperFacadeImpl.java:740)
    ... 59 more

Don't loose Map instance when mapping MultiOccurenceVariable to a Map

When mapping a MultiOccurenceVariable (e.g. List or Set) to a Map, a temporary List of MapEntries is used. But in the end where all temporarily created entries should be added to the target Map an assignment to a local variable is done and the original reference of the target map is lost.

I wrote a minimal test for this case and my result without my patch was an empty Map. But it should be at least not empty. This only happens if you map directly with type information provided by TypeBuilder. When I wrap the Set and Map into classes all works fine. Even mapAsMap is working.

The basic twist of this test looks as follows

        Set<A> categories = new HashSet<A>(asList(new A("a"), new A("b")));
        Map<String, String> categoryMap = mapper.map(categories, SET, MAP);

I already have a fully implemented pull request on the way which I will post in the upcomming days.

Default mapper with SortedSet throws ClassCastException

(Gist test case: https://gist.github.com/f537ae568a26d08163b8)

Using Orika 1.4.5 to map a bean with SortedSet, it throws the following exception:

ma.glasnost.orika.MappingException: While attempting the following mapping:
sourceClass = class orika.SortedSetTest$Foo
destinationType = orika.SortedSetTest.Bar
resolvedStrategy = InstantiateAndUseCustomMapperStrategy<Foo, Bar> {customMapper: GeneratedMapper<Foo, Bar> {usedConverters: [], usedMappers: [], usedMapperFacades: [], usedTypes: [String] }, unenhancer: ma.glasnost.orika.unenhance.BaseUnenhancer@56528192, objectFactory: DefaultConstructorObjectFactory<Bar>}
Error occurred: java.lang.ClassCastException: java.util.LinkedHashSet cannot be cast to java.util.SortedSet
-----begin dump of current state-----------------------------
Registered object factories: 1 (approximate size: 27.3 kB)
  [Bar] : {Foo=DefaultConstructorObjectFactory<Bar>}
-------------------------------------------------------------
Registered mappers: 1 (approximate size: 887.1 kB)
  [0] : GeneratedMapper<Foo, Bar> {usedConverters: [], usedMappers: [], usedMapperFacades: [], usedTypes: [String] }
-------------------------------------------------------------
Registered concrete types: 5 (approximate size: 136.0 kB)
  [interface java.util.Collection] : ArrayList<Object>
  [interface java.util.List] : ArrayList<Object>
  [interface java.util.Map$Entry] : MapEntry<Object, Object>
  [interface java.util.Set] : LinkedHashSet<Object>
  [interface java.util.Map] : LinkedHashMap<Object, Object>
-------------------------------------------------------------
Resolved strategies: 1 (approximate size: 1,012.4 kB)
{source: Foo, dest: Bar, in-place:false}: InstantiateAndUseCustomMapperStrategy<Foo, Bar> {customMapper: GeneratedMapper<Foo, Bar> {usedConverters: [], usedMappers: [], usedMapperFacades: [], usedTypes: [String] }, unenhancer: ma.glasnost.orika.unenhance.BaseUnenhancer@56528192, objectFactory: DefaultConstructorObjectFactory<Bar>}
-------------------------------------------------------------
Unenhance strategy: ma.glasnost.orika.unenhance.BaseUnenhancer@56528192
-----end dump of current state-------------------------------
    at ma.glasnost.orika.impl.ExceptionUtility.newMappingException(ExceptionUtility.java:55)
    at ma.glasnost.orika.impl.MapperFacadeImpl.map(MapperFacadeImpl.java:745)
    at ma.glasnost.orika.impl.MapperFacadeImpl.map(MapperFacadeImpl.java:714)
    at orika.SortedSetTest.shouldMapSortedSet(SortedSetTest.java:47)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:78)
    at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:212)
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:68)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140)
Caused by: java.lang.ClassCastException: java.util.LinkedHashSet cannot be cast to java.util.SortedSet
    at ma.glasnost.orika.generated.Orika_Bar_Foo_Mapper44633627972572$0.mapAtoB(Orika_Bar_Foo_Mapper44633627972572$0.java)
    at ma.glasnost.orika.impl.mapping.strategy.UseCustomMapperStrategy.map(UseCustomMapperStrategy.java:67)
    at ma.glasnost.orika.impl.MapperFacadeImpl.map(MapperFacadeImpl.java:735)
    ... 29 more

It seems like SortedSet is not identified by the default mapper, and it tries to use LinkedHashSet instead.

java.lang.IllegalArgumentException: no suitable constructors found for ZonedDateTime

Version used is 1.4.6 running in JDK 1.8

The following exception is happening:

Caused by: java.lang.IllegalArgumentException: no suitable constructors found for ZonedDateTime
        at ma.glasnost.orika.impl.generator.ObjectFactoryGenerator.addSourceClassConstructor(ObjectFactoryGenerator.java:165) ~[orika-core-1.4.6.jar:na]
        at ma.glasnost.orika.impl.generator.ObjectFactoryGenerator.addCreateMethod(ObjectFactoryGenerator.java:124) ~[orika-core-1.4.6.jar:na]
        at ma.glasnost.orika.impl.generator.ObjectFactoryGenerator.build(ObjectFactoryGenerator.java:95) ~[orika-core-1.4.6.jar:na]

Thanks

Registering map with multiple converters does not work

When using date converter for 2 different formats for the same class but 2 different fields, this used to work for version 1.4.4, but since 1.4.5 it does not work anymore. I am not sure if this is a new feature difference or not. But I can see in the generated code that in 1.4.4 it can see 2 converters, and 1.4.6 the mapping code is generated with both field mapping using the first converters.

When I step into the code, in 1.4.5 and above versions, it shows only 1 converter in the converter factory. This feels like a breakage to me, but it's been 2 releases and no one seemed to notice it, I hope this is no intended?

Note that I've tried this in 1.4.5, 1.4.6 and also in the latest 1.5.0 beta, all have the same behavior.

orika-date-mapping-test.zip

Linkage problem when orika and the domain model are in different classloaders

In a scenario where the Orika classes and the mapped classes are loaded by different classloaders, it is possible to create the mapper, but have it fail during linkage.

Consider the following class.

    package example;

    import ma.glasnost.orika.*;
    import ma.glasnost.orika.impl.*;

    public class Example {
            public static class A { }
            public static class B { }

            public static void main(String... args) {
                    MapperFactory mapperFactory = new DefaultMapperFactory.Builder().build();
                    mapperFactory.classMap(A.class, B.class).register();
                    BoundMapperFacade<A, B> facade = mapperFactory.getMapperFacade(A.class, B.class);
                    facade.map(new A());
            }
    }

Running it (with Orika + dependencies on the classpath) produces no runtime errors.

Now package the compiled Example classes in an example.jar and load them with the following runner:

    import java.net.URLClassLoader;
    import java.io.File;
    import java.net.URL;
    import java.lang.reflect.*;

    public class Runner {
            public static void main(String... args) throws Exception {
                    URLClassLoader cl = new URLClassLoader(new URL[] {new File("example.jar").toURL()}, Runner.class.getClassLoader());
                    Thread.currentThread().setContextClassLoader(cl);

                    Class<?> example = cl.loadClass("example.Example");
                    Method main = example.getMethod("main", args.getClass());
                    main.invoke(null, new Object[] { args });
            }
    }

Executing Runner in a classpath containing Orika + dependencies results in a runtime failure.

    Exception in thread "main" java.lang.reflect.InvocationTargetException
            at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
            at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
            at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
            at java.lang.reflect.Method.invoke(Method.java:497)
            at Runner.main(Runner.java:13)
    Caused by: java.lang.NoClassDefFoundError: example/Example$A
            at ma.glasnost.orika.generated.Orika_B_A_Mapper1965230208308$0.mapAtoB(Orika_B_A_Mapper1965230208308$0.java)
            at ma.glasnost.orika.impl.mapping.strategy.UseCustomMapperStrategy.map(UseCustomMapperStrategy.java:67)
            at ma.glasnost.orika.impl.DefaultBoundMapperFacade.map(DefaultBoundMapperFacade.java:137)
            at ma.glasnost.orika.impl.DefaultBoundMapperFacade.map(DefaultBoundMapperFacade.java:94)
            at example.Example.main(Example.java:14)
            ... 5 more
    Caused by: java.lang.ClassNotFoundException: example.Example$A
            at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
            at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
            at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
            at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
            ... 10 more

This scenario is an extreme simplification of the case where Orika is on the classpath of a (web/ee) container and the domain model is inside a WAR file.

This behaviour is related to the classloader that is used to load the generated classfile. This choice is made near the end of JavassistCompilerStrategy in the call to byteCodeClass.toClass. It currently uses the classloader that loaded that class. Given the context classloader is considered during the compilation of the generated class, it seems reasonable to us to also use it when loading the generated class. I can confirm that making such a change fixes both this simplified example and our real-world use case.

NPE on VariableRef.isPrimitive() with map of map

When mapping something with a map of map, a NullPointerException occurs in isPrimitive() called by MapToMap.generateMappingCode().

I think this is the same issue as reported in https://code.google.com/p/orika/issues/detail?id=170&q=NPE

See https://github.com/marcpa00/orika-issue-mapOfMap for unit tests showing the problem.

This was tested with 1.4.6.
Project above shows that a Map<Date, Integer> works ok, but a Map<Date, Map<Integer, String>> does not.

Mapping to java.lang.Map

I am trying to map my Java POJO to java.lang.Map but i am getting error similar to one discussed in link.

https://code.google.com/p/orika/issues/detail?id=146

Full stack trace which i am getting.

ma.glasnost.orika.MappingException: While attempting the following mapping:
sourceClass = class de.hybris.platform.commercefacades.order.data.OrderData
destinationType = java.util.Map<Object, Object>
Error occurred: com.thoughtworks.paranamer.ParameterNamesNotFoundException: One or more @Named annotations missing for class 'java.util.LinkedHashMap', methodOrCtor <init> and parameter types int,float,boolean

-----begin dump of current state-----------------------------
Registered object factories: 0 (approximate size: 0.1 kB)
-------------------------------------------------------------
Registered mappers: 0 (approximate size: 0.4 kB)
-------------------------------------------------------------
Registered concrete types: 5 (approximate size: 114.1 kB)
  [interface java.util.List] : ArrayList<Object>
  [interface java.util.Map$Entry] : MapEntry<Object, Object>
  [interface java.util.Map] : LinkedHashMap<Object, Object>
  [interface java.util.Set] : LinkedHashSet<Object>
  [interface java.util.Collection] : ArrayList<Object>
-------------------------------------------------------------
Resolved strategies: 0 (approximate size: 73.9 kB)
-------------------------------------------------------------
Unenhance strategy: ma.glasnost.orika.unenhance.BaseUnenhancer@48ea2003
-----end dump of current state-------------------------------
    at ma.glasnost.orika.impl.ExceptionUtility.newMappingException(ExceptionUtility.java:55)
    at ma.glasnost.orika.impl.MapperFacadeImpl.map(MapperFacadeImpl.java:273)
    at ma.glasnost.orika.impl.MapperFacadeImpl.map(MapperFacadeImpl.java:243)
    at ma.glasnost.orika.impl.MapperFacadeImpl.mapAsCollection(MapperFacadeImpl.java:555)
    at ma.glasnost.orika.impl.MapperFacadeImpl.mapAsCollection(MapperFacadeImpl.java:1034)
    at ma.glasnost.orika.impl.ConfigurableMapper.mapAsCollection(ConfigurableMapper.java:282)
    at de.hybris.platform.commercewebservicescommons.mapping.impl.DefaultDataMapper.mapAsCollection(DefaultDataMapper.java:234)
    at org.abc.controllers.TypeServiceController.getTypes(TypeServiceController.java:41)
    at org.abc.controllers.TypeServiceControllerTest.getTypes(TypeServiceControllerTest.java:45)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:119)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:42)
    at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:234)
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:74)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)
Caused by: com.thoughtworks.paranamer.ParameterNamesNotFoundException: One or more @Named annotations missing for class 'java.util.LinkedHashMap', methodOrCtor <init> and parameter types int,float,boolean
    at com.thoughtworks.paranamer.AnnotationParanamer.lookupParameterNames(AnnotationParanamer.java:129)
    at com.thoughtworks.paranamer.AdaptiveParanamer.lookupParameterNames(AdaptiveParanamer.java:75)
    at com.thoughtworks.paranamer.CachingParanamer.lookupParameterNames(CachingParanamer.java:79)
    at com.thoughtworks.paranamer.CachingParanamer.lookupParameterNames(CachingParanamer.java:72)
    at ma.glasnost.orika.constructor.ConstructorParameterResolver.getProperties(ConstructorParameterResolver.java:63)
    at ma.glasnost.orika.constructor.ConstructorParameterResolver.getPossibleConstructorParams(ConstructorParameterResolver.java:119)
    at ma.glasnost.orika.property.PropertyResolver.resolveConstructorProperty(PropertyResolver.java:701)
    at ma.glasnost.orika.property.PropertyResolver.getProperty(PropertyResolver.java:686)
    at ma.glasnost.orika.property.PropertyResolver.getProperty(PropertyResolver.java:616)
    at ma.glasnost.orika.metadata.ClassMapBuilder.resolveProperty(ClassMapBuilder.java:828)
    at ma.glasnost.orika.metadata.ClassMapBuilderForMaps.resolveProperty(ClassMapBuilderForMaps.java:176)
    at ma.glasnost.orika.metadata.FieldMapBuilder.<init>(FieldMapBuilder.java:78)
    at ma.glasnost.orika.metadata.FieldMapBuilder.<init>(FieldMapBuilder.java:61)
    at ma.glasnost.orika.metadata.ClassMapBuilder.fieldMap(ClassMapBuilder.java:309)
    at ma.glasnost.orika.metadata.ClassMapBuilderForMaps.fieldMap(ClassMapBuilderForMaps.java:157)
    at ma.glasnost.orika.metadata.ClassMapBuilderForMaps.byDefault(ClassMapBuilderForMaps.java:129)
    at ma.glasnost.orika.metadata.ClassMapBuilderForMaps.byDefault(ClassMapBuilderForMaps.java:38)
    at ma.glasnost.orika.metadata.ClassMapBuilder.byDefault(ClassMapBuilder.java:559)
    at ma.glasnost.orika.impl.DefaultMapperFactory.lookupMapper(DefaultMapperFactory.java:750)
    at ma.glasnost.orika.impl.DefaultMapperFactory.lookupMapper(DefaultMapperFactory.java:707)
    at ma.glasnost.orika.impl.MapperFacadeImpl.resolveMapper(MapperFacadeImpl.java:584)
    at ma.glasnost.orika.impl.MapperFacadeImpl.resolveMappingStrategy(MapperFacadeImpl.java:216)
    at ma.glasnost.orika.impl.MapperFacadeImpl.map(MapperFacadeImpl.java:261)
    ... 34 more

Nested fieldname with the name 'enabled' causes javaassit error

When a nested field is mapped with name enabled like the following:

            .field("items{enabled}", "items{enabled}").mapNulls(false)

This causes a the following error at compile time: compile error: no such field: java

stack trace:

09:46:46,877 ERROR [org.jboss.msc.service.fail](MSC service thread 1-4) MSC000001: Failed to start service jboss.deployment.unit."ordercloud.war".INSTALL: org.jboss.msc.service.StartException in service jboss.deployment.unit."ordercloud.war".INSTALL: WFLYSRV0153: Failed to process phase INSTALL of deployment "ordercloud.war"
at org.jboss.as.server.deployment.DeploymentUnitPhaseService.start(DeploymentUnitPhaseService.java:163)
at org.jboss.msc.service.ServiceControllerImpl$StartTask.startService(ServiceControllerImpl.java:1948)
at org.jboss.msc.service.ServiceControllerImpl$StartTask.run(ServiceControllerImpl.java:1881)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.ExceptionInInitializerError
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:278)
at org.jboss.invocation.proxy.AbstractProxyFactory.afterClassLoad(AbstractProxyFactory.java:95)
at org.jboss.invocation.proxy.AbstractClassFactory.defineClass(AbstractClassFactory.java:166)
at org.jboss.invocation.proxy.AbstractProxyFactory.getCachedMethods(AbstractProxyFactory.java:150)
at org.jboss.as.ejb3.component.stateless.StatelessComponentDescription$3.configure(StatelessComponentDescription.java:150)
at org.jboss.as.ee.component.DefaultComponentViewConfigurator.configure(DefaultComponentViewConfigurator.java:67)
at org.jboss.as.ee.component.deployers.EEModuleConfigurationProcessor.deploy(EEModuleConfigurationProcessor.java:81)
at org.jboss.as.server.deployment.DeploymentUnitPhaseService.start(DeploymentUnitPhaseService.java:156)
... 5 more
Caused by: ma.glasnost.orika.MappingException: ma.glasnost.orika.impl.generator.CompilerStrategy$SourceCodeGenerationException: Error compiling ma.glasnost.orika.generated.Orika_OrdersDto_Orders_Mapper198327897925844$0
at ma.glasnost.orika.impl.generator.MapperGenerator.build(MapperGenerator.java:105)
at ma.glasnost.orika.impl.DefaultMapperFactory.buildMapper(DefaultMapperFactory.java:1372)
at ma.glasnost.orika.impl.DefaultMapperFactory.build(DefaultMapperFactory.java:1199)
at ma.glasnost.orika.impl.DefaultMapperFactory.getMapperFacade(DefaultMapperFactory.java:859)
at com.unijunction.ordercloud.order.mapper.OrderMapper.(OrderMapper.java:51)
... 14 more
Caused by: ma.glasnost.orika.impl.generator.CompilerStrategy$SourceCodeGenerationException: Error compiling ma.glasnost.orika.generated.Orika_OrdersDto_Orders_Mapper198327897925844$0
at ma.glasnost.orika.impl.generator.JavassistCompilerStrategy.compileClass(JavassistCompilerStrategy.java:269)
at ma.glasnost.orika.impl.generator.SourceCodeContext.compileClass(SourceCodeContext.java:249)
at ma.glasnost.orika.impl.generator.SourceCodeContext.getInstance(SourceCodeContext.java:266)
at ma.glasnost.orika.impl.generator.MapperGenerator.build(MapperGenerator.java:75)
... 18 more
Caused by: javassist.CannotCompileException: [source error] no such field: java
at javassist.CtNewMethod.make(CtNewMethod.java:79)
at javassist.CtNewMethod.make(CtNewMethod.java:45)
at ma.glasnost.orika.impl.generator.JavassistCompilerStrategy.compileClass(JavassistCompilerStrategy.java:253)
... 21 more
Caused by: compile error: no such field: java
at javassist.compiler.MemberResolver.lookupField(MemberResolver.java:311)
at javassist.compiler.MemberResolver.lookupFieldByJvmName(MemberResolver.java:297)
at javassist.compiler.TypeChecker.fieldAccess(TypeChecker.java:850)
at javassist.compiler.TypeChecker.atFieldRead(TypeChecker.java:777)
at javassist.compiler.TypeChecker.atExpr(TypeChecker.java:578)
at javassist.compiler.ast.Expr.accept(Expr.java:68)
at javassist.compiler.TypeChecker.fieldAccess(TypeChecker.java:834)
at javassist.compiler.TypeChecker.atFieldRead(TypeChecker.java:777)
at javassist.compiler.TypeChecker.atExpr(TypeChecker.java:578)
at javassist.compiler.ast.Expr.accept(Expr.java:68)
at javassist.compiler.TypeChecker.atCallExpr(TypeChecker.java:660)
at javassist.compiler.JvstTypeChecker.atCallExpr(JvstTypeChecker.java:157)
at javassist.compiler.ast.CallExpr.accept(CallExpr.java:46)
at javassist.compiler.TypeChecker.booleanExpr(TypeChecker.java:518)
at javassist.compiler.TypeChecker.atBinExpr(TypeChecker.java:337)
at javassist.compiler.ast.BinExpr.accept(BinExpr.java:41)
at javassist.compiler.TypeChecker.booleanExpr(TypeChecker.java:527)
at javassist.compiler.TypeChecker.atBinExpr(TypeChecker.java:337)
at javassist.compiler.ast.BinExpr.accept(BinExpr.java:41)
at javassist.compiler.TypeChecker.booleanExpr(TypeChecker.java:523)
at javassist.compiler.TypeChecker.atExpr(TypeChecker.java:592)
at javassist.compiler.ast.Expr.accept(Expr.java:68)
at javassist.compiler.TypeChecker.booleanExpr(TypeChecker.java:527)
at javassist.compiler.TypeChecker.atBinExpr(TypeChecker.java:337)
at javassist.compiler.ast.BinExpr.accept(BinExpr.java:41)
at javassist.compiler.TypeChecker.booleanExpr(TypeChecker.java:526)
at javassist.compiler.TypeChecker.atBinExpr(TypeChecker.java:337)
at javassist.compiler.ast.BinExpr.accept(BinExpr.java:41)
at javassist.compiler.TypeChecker.booleanExpr(TypeChecker.java:526)
at javassist.compiler.TypeChecker.atBinExpr(TypeChecker.java:337)
at javassist.compiler.ast.BinExpr.accept(BinExpr.java:41)
at javassist.compiler.TypeChecker.booleanExpr(TypeChecker.java:526)
at javassist.compiler.TypeChecker.atBinExpr(TypeChecker.java:337)
at javassist.compiler.ast.BinExpr.accept(BinExpr.java:41)
at javassist.compiler.TypeChecker.booleanExpr(TypeChecker.java:526)
at javassist.compiler.TypeChecker.atBinExpr(TypeChecker.java:337)
at javassist.compiler.ast.BinExpr.accept(BinExpr.java:41)
at javassist.compiler.TypeChecker.booleanExpr(TypeChecker.java:526)
at javassist.compiler.TypeChecker.atBinExpr(TypeChecker.java:337)
at javassist.compiler.ast.BinExpr.accept(BinExpr.java:41)
at javassist.compiler.TypeChecker.booleanExpr(TypeChecker.java:526)
at javassist.compiler.TypeChecker.atBinExpr(TypeChecker.java:337)
at javassist.compiler.ast.BinExpr.accept(BinExpr.java:41)
at javassist.compiler.CodeGen.doTypeCheck(CodeGen.java:242)
at javassist.compiler.CodeGen.compileBooleanExpr(CodeGen.java:236)
at javassist.compiler.CodeGen.atIfStmnt(CodeGen.java:384)
at javassist.compiler.CodeGen.atStmnt(CodeGen.java:355)
at javassist.compiler.ast.Stmnt.accept(Stmnt.java:50)
at javassist.compiler.CodeGen.atStmnt(CodeGen.java:351)
at javassist.compiler.ast.Stmnt.accept(Stmnt.java:50)
at javassist.compiler.CodeGen.atWhileStmnt(CodeGen.java:431)
at javassist.compiler.CodeGen.atStmnt(CodeGen.java:357)
at javassist.compiler.ast.Stmnt.accept(Stmnt.java:50)
at javassist.compiler.CodeGen.atStmnt(CodeGen.java:351)
at javassist.compiler.ast.Stmnt.accept(Stmnt.java:50)
at javassist.compiler.CodeGen.atIfStmnt(CodeGen.java:391)
at javassist.compiler.CodeGen.atStmnt(CodeGen.java:355)
at javassist.compiler.ast.Stmnt.accept(Stmnt.java:50)
at javassist.compiler.CodeGen.atStmnt(CodeGen.java:351)
at javassist.compiler.ast.Stmnt.accept(Stmnt.java:50)
at javassist.compiler.CodeGen.atMethodBody(CodeGen.java:292)
at javassist.compiler.CodeGen.atMethodDecl(CodeGen.java:274)
at javassist.compiler.ast.MethodDecl.accept(MethodDecl.java:44)
at javassist.compiler.Javac.compileMethod(Javac.java:169)
at javassist.compiler.Javac.compile(Javac.java:95)
at javassist.CtNewMethod.make(CtNewMethod.java:74)
... 23 more

Mapping java.util.Map attribute to java.util.HashMap throws MappingException

Mapping a java.util.Map attribute to a java.util.HashMap one throws a MappingException:

Caused by: java.lang.ClassCastException: java.lang.Boolean cannot be cast to java.util.HashMap
at ma.glasnost.orika.generated.Orika_Destination_Source_Mapper32463485991091$0.mapAtoB(Orika_Destination_Source_Mapper32463485991091$0.java)
at ma.glasnost.orika.impl.mapping.strategy.UseCustomMapperStrategy.map(UseCustomMapperStrategy.java:67)
at ma.glasnost.orika.impl.MapperFacadeImpl.map(MapperFacadeImpl.java:742)
... 25 more

Used Version: 1.4.6

Test Case:

import java.util.HashMap;
import java.util.Map;

import ma.glasnost.orika.MapperFactory;
import ma.glasnost.orika.impl.DefaultMapperFactory;

import org.junit.Assert;
import org.junit.Test;

public class IssueMapToHashMapTest {

        @Test
        public void mapTest() {
                try {

                        final MapperFactory mapperFactory = new DefaultMapperFactory.Builder()
                                        .build();

                        Source input = new Source();

                        Map<String, String> map = new HashMap<String, String>();

                        map.put("key_1", "value_1");
                        map.put("key_2", "value_2");

                        input.setMap(map);

                        Destination output = mapperFactory.getMapperFacade().map(input,
                                        Destination.class);

                        Assert.assertNotNull(output);
                        Assert.assertNotNull(output.getMap());
                        Assert.assertTrue(output.getMap().size() > 0);
                        Assert.assertTrue(output.getMap().get("key_1").equals("value_1"));
                        Assert.assertTrue(output.getMap().get("key_2").equals("value_2"));

                } catch (Throwable th) {
                        System.err.println(th.toString());
                        th.printStackTrace();
                        Assert.fail(th.toString());
                }

        }

        public static class Source {
                private Map<String, String> map;

                public Map<String, String> getMap() {
                        return map;
                }

                public void setMap(Map<String, String> mappa) {
                        this.map = mappa;
                }

        }

        public static class Destination {
                private HashMap<String, String> map;

                public HashMap<String, String> getMap() {
                        return map;
                }

                public void setMap(HashMap<String, String> mappa) {
                        this.map = mappa;
                }

        }

}

Mapping nested multi-occurrence elements failed

I failed in the demo: Mapping nested multi-occurrence elements.
The version of orika is 1.5.0-beta0.
the following are my codes:

public class Name {
    private String first;
    private String last;
    private String fullName;

    public Name() {
    }

    public Name(String first, String last, String fullName) {
        this.first = first;
        this.last = last;
        this.fullName = fullName;
    }

    public String getFirst() {
        return first;
    }

    public void setFirst(String first) {
        this.first = first;
    }

    public String getLast() {
        return last;
    }

    public void setLast(String last) {
        this.last = last;
    }

    public String getFullName() {
        return fullName;
    }

    public void setFullName(String fullName) {
        this.fullName = fullName;
    }
}
public class Person {
    private List<Name> names;

    public List<Name> getNames() {
        return names;
    }

    public void setNames(List<Name> names) {
        this.names = names;
    }
}
public class PersonDto {
    private Map<String, Name> personalNames;
    private String[] firstNames;
    private List<String> lastNames;

    public Map<String, Name> getPersonalNames() {
        return personalNames;
    }

    public void setPersonalNames(Map<String, Name> personalNames) {
        this.personalNames = personalNames;
    }

    public String[] getFirstNames() {
        return firstNames;
    }

    public void setFirstNames(String[] firstNames) {
        this.firstNames = firstNames;
    }

    public List<String> getLastNames() {
        return lastNames;
    }

    public void setLastNames(List<String> lastNames) {
        this.lastNames = lastNames;
    }
}

test

public static void main(String[] args) {
        MapperFactory factory = new DefaultMapperFactory.Builder().build();
        factory.classMap(Person.class, PersonDto.class)
            .field("names{fullName}", "personalNames{key}")
            .field("names{}", "personalNames{value}")
            .register();

        Person source = new Person();
        List<Name> names = new ArrayList<Name>();
        Name n1 = new Name();
        n1.setFirst("Wangcai");
        n1.setLast("Li");
        n1.setFullName("Wangcai Li");
        Name n2 = new Name();
        n2.setFirst("Achun");
        n2.setLast("Fu");
        n2.setFullName("Achun Fu");
        names.add(n1);
        names.add(n2);
        source.setNames(names);
        factory.getMapperFacade().map(source, PersonDto.class);
    }

the error messages:

08:49:00.537 [main] DEBUG m.g.orika.metadata.ClassMapBuilder - ClassMap created:
    ClassMapBuilder.map(Person, PersonDto)
     .field( names{fullName}(String), personalNames{key}(String) )
     .field( names{}(Name), personalNames{value}(Name) )
08:49:00.600 [main] DEBUG m.g.orika.metadata.ClassMapBuilder - ClassMap created:
    ClassMapBuilder.map(Name, MapEntry<String, Name>)
     .field( fullName(String), key(String) )
     .field( (Name), value(Name) )
08:49:00.693 [main] DEBUG m.g.o.impl.generator.MapperGenerator - Generating new mapper for (Name, MapEntry<String, Name>)
    Orika_MapEntry_Name_Mapper2084152091765$1.mapAToB(Name, MapEntry) {
     Field(fullName(String), key(String)) : copying String by reference
     Field((Name), value(Name)) : mapping object to object
    }
    Orika_MapEntry_Name_Mapper2084152091765$1.mapBToA(MapEntry<String, Name>, Name) {
     Field(key(String), fullName(String)) : copying String by reference
     Field(value(Name), (Name)) : mapping object to object
    }
    BoundMapperFacades used: [DefaultBoundMapperFacade<Name, Name>]
08:49:00.709 [main] DEBUG m.g.orika.metadata.ClassMapBuilder - ClassMap created:
    ClassMapBuilder.map(Entry<String, Name>, Name)
     .field( key(String), fullName(String) )
     .field( value(Name), (Name) )
08:49:00.709 [main] DEBUG m.g.o.impl.generator.MapperGenerator - Generating new mapper for (Entry<String, Name>, Name)
    Orika_Name_Entry_Mapper2084247853307$2.mapAToB(Entry<String, Name>, Name) {
     Field(key(String), fullName(String)) : copying String by reference
     Field(value(Name), (Name)) : mapping object to object
    }
    Orika_Name_Entry_Mapper2084247853307$2.mapBToA(Name, Entry) {
     Field(fullName(String), key(String)) : excluding because Entry<String, Name>.key(String) is not assignable and cannot be mapped in-place
     Field((Name), value(Name)) : mapping object to object
    }
    BoundMapperFacades used: [DefaultBoundMapperFacade<Name, Name>]
08:49:00.756 [main] DEBUG m.g.o.impl.generator.MapperGenerator - Generating new mapper for (Person, PersonDto)
    Orika_PersonDto_Person_Mapper2084141036151$0.mapAToB(Person, PersonDto) {
     Field(names{fullName}(String), personalNames{key}(String)) : copying String by reference
     Field(names{}(Name), personalNames{value}(Name)) : mapping object to object
    }
    Orika_PersonDto_Person_Mapper2084141036151$0.mapBToA(PersonDto, Person) {
     Field(personalNames{key}(String), names{fullName}(String)) : copying String by reference
     Field(personalNames{value}(Name), names{}(Name)) : mapping object to object
    }
    Types used: [List<Name>, ArrayList<MapEntry<String, Name>>, Map<String, Name>]
    BoundMapperFacades used: [DefaultBoundMapperFacade<Name, MapEntry<String, Name>>, DefaultBoundMapperFacade<Name, Name>, DefaultBoundMapperFacade<Entry<String, Name>, Name>]
08:49:00.756 [main] DEBUG m.g.orika.impl.MapperFacadeImpl - MappingStrategy resolved and cached:
    Inputs:[ sourceClass: org.ys.orika.Person, sourceType: null, destinationType: class org.ys.orika.PersonDto]
    Resolved:[ strategy: InstantiateAndUseCustomMapperStrategy, sourceType: Person, destinationType: PersonDto, mapper: GeneratedMapper<Person, PersonDto> {usedConverters: [], usedMappers: [], usedMapperFacades: [DefaultBoundMapperFacade<Name, MapEntry<String, Name>>, DefaultBoundMapperFacade<Name, Name>, DefaultBoundMapperFacade<Entry<String, Name>, Name>], usedTypes: [List<Name>, ArrayList<MapEntry<String, Name>>, Map<String, Name>] }, mapReverse?: false]
08:49:00.771 [main] DEBUG m.g.o.i.g.ObjectFactoryGenerator - Generating new object factory for (MapEntry<String, Name>)
    Using constructor: public ma.glasnost.orika.MapEntry(java.lang.Object,java.lang.Object)
     Field(fullName(String), key(Object)) : copying null by reference
     Field((Name), value(Object)) : mapping object to object
    BoundMapperFacades used: [DefaultBoundMapperFacade<Name, Object>]
08:49:00.771 [main] DEBUG m.g.orika.impl.DefaultMapperFactory - No mapper registered for (Name, Object): attempting to generate
08:49:00.771 [main] DEBUG m.g.orika.metadata.ClassMapBuilder - ClassMap created:
    ClassMapBuilder.map(Name, Object)
08:49:00.771 [main] DEBUG m.g.o.impl.generator.MapperGenerator - Generating new mapper for (Name, Object)
    Orika_Object_Name_Mapper2084309873285$4.mapAToB(Name, Object) {
    }
    Orika_Object_Name_Mapper2084309873285$4.mapBToA(Object, Name) {
    }
08:49:00.771 [main] DEBUG m.g.orika.impl.MapperFacadeImpl - MappingStrategy resolved and cached:
    Inputs:[ sourceClass: org.ys.orika.Name, sourceType: Name, destinationType: Object]
    Resolved:[ strategy: InstantiateAndUseCustomMapperStrategy, sourceType: Name, destinationType: Object, mapper: GeneratedMapper<Name, Object> {usedConverters: [], usedMappers: [], usedMapperFacades: [], usedTypes: [] }, mapReverse?: false]
Exception in thread "main" ma.glasnost.orika.MappingException: While attempting the following mapping:
sourceClass = class org.ys.orika.Person
destinationType = org.ys.orika.PersonDto
resolvedStrategy = InstantiateAndUseCustomMapperStrategy<Person, PersonDto> {customMapper: GeneratedMapper<Person, PersonDto> {usedConverters: [], usedMappers: [], usedMapperFacades: [DefaultBoundMapperFacade<Name, MapEntry<String, Name>>, DefaultBoundMapperFacade<Name, Name>, DefaultBoundMapperFacade<Entry<String, Name>, Name>], usedTypes: [List<Name>, ArrayList<MapEntry<String, Name>>, Map<String, Name>] }, unenhancer: ma.glasnost.orika.unenhance.BaseUnenhancer@f43dac, objectFactory: DefaultConstructorObjectFactory<PersonDto>}
Error occurred: java.lang.ClassCastException: java.lang.Object cannot be cast to org.ys.orika.Name
-----begin dump of current state-----------------------------
Registered object factories: 3 (approximate size: 1,587.1 kB)
  [MapEntry<String, Name>] : {Name=ma.glasnost.orika.generated.MapEntry_Name_ObjectFactory20840540034162084299463003$3@caad9a}
  [PersonDto] : {Person=DefaultConstructorObjectFactory<PersonDto>}
  [Object] : {Name=DefaultConstructorObjectFactory<Object>}
-------------------------------------------------------------
Registered mappers: 4 (approximate size: 1,830.2 kB)
  [0] : GeneratedMapper<Name, MapEntry<String, Name>> {usedConverters: [], usedMappers: [], usedMapperFacades: [DefaultBoundMapperFacade<Name, Name>], usedTypes: [] }
  [1] : GeneratedMapper<Person, PersonDto> {usedConverters: [], usedMappers: [], usedMapperFacades: [DefaultBoundMapperFacade<Name, MapEntry<String, Name>>, DefaultBoundMapperFacade<Name, Name>, DefaultBoundMapperFacade<Entry<String, Name>, Name>], usedTypes: [List<Name>, ArrayList<MapEntry<String, Name>>, Map<String, Name>] }
  [2] : GeneratedMapper<Entry<String, Name>, Name> {usedConverters: [], usedMappers: [], usedMapperFacades: [DefaultBoundMapperFacade<Name, Name>], usedTypes: [] }
  [3] : GeneratedMapper<Name, Object> {usedConverters: [], usedMappers: [], usedMapperFacades: [], usedTypes: [] }
-------------------------------------------------------------
Registered concrete types: 5 (approximate size: 132.0 kB)
  [interface java.util.Map] : LinkedHashMap<Object, Object>
  [interface java.util.List] : ArrayList<Object>
  [interface java.util.Collection] : ArrayList<Object>
  [interface java.util.Map$Entry] : MapEntry<Object, Object>
  [interface java.util.Set] : LinkedHashSet<Object>
-------------------------------------------------------------
Resolved strategies: 2 (approximate size: 1,777.0 kB)
{source: Person, dest: PersonDto, in-place:false}: InstantiateAndUseCustomMapperStrategy<Person, PersonDto> {customMapper: GeneratedMapper<Person, PersonDto> {usedConverters: [], usedMappers: [], usedMapperFacades: [DefaultBoundMapperFacade<Name, MapEntry<String, Name>>, DefaultBoundMapperFacade<Name, Name>, DefaultBoundMapperFacade<Entry<String, Name>, Name>], usedTypes: [List<Name>, ArrayList<MapEntry<String, Name>>, Map<String, Name>] }, unenhancer: ma.glasnost.orika.unenhance.BaseUnenhancer@f43dac, objectFactory: DefaultConstructorObjectFactory<PersonDto>}
{source: Name, dest: Object, in-place:false}: InstantiateAndUseCustomMapperStrategy<Name, Object> {customMapper: GeneratedMapper<Name, Object> {usedConverters: [], usedMappers: [], usedMapperFacades: [], usedTypes: [] }, unenhancer: ma.glasnost.orika.unenhance.BaseUnenhancer@f43dac, objectFactory: DefaultConstructorObjectFactory<Object>}
-------------------------------------------------------------
Unenhance strategy: ma.glasnost.orika.unenhance.BaseUnenhancer@f43dac
-----end dump of current state-------------------------------
    at ma.glasnost.orika.impl.ExceptionUtility.newMappingException(ExceptionUtility.java:55)
    at ma.glasnost.orika.impl.MapperFacadeImpl.map(MapperFacadeImpl.java:754)
    at ma.glasnost.orika.impl.MapperFacadeImpl.map(MapperFacadeImpl.java:723)
    at org.ys.orika.TestMulti.main(TestMulti.java:31)
Caused by: java.lang.ClassCastException: java.lang.Object cannot be cast to org.ys.orika.Name
    at ma.glasnost.orika.generated.Orika_PersonDto_Person_Mapper2084141036151$0.mapAtoB(Orika_PersonDto_Person_Mapper2084141036151$0.java)
    at ma.glasnost.orika.impl.mapping.strategy.UseCustomMapperStrategy.map(UseCustomMapperStrategy.java:67)
    at ma.glasnost.orika.impl.MapperFacadeImpl.map(MapperFacadeImpl.java:744)
    ... 2 more

Exclude() is not working as expected.

Hi! there,

I am using Orika 1.4.6 and Hibernate 4. I want to exclude a property from mapping. I used exclude() but its not working as expected.

Whats happening: when I make a field to exclude (instead of ignoring), it sets the target hibernate entitys' property to null (I think because its setting the source bean property to null instead of ignoring it). This will in turn sets the field to NULL in the database while saving that entity.

Heres the conceptual class diagram:

orikatestdiagram

I am using using the following configuration:

new DefaultMapperFactory.Builder().compilerStrategy(new JavassistCompilerStrategy()).unenhanceStrategy(new HibernateUnenhanceStrategy()).build()

Any suggestion will be appreciated!

If you want more information please let me know, and I can post an example if needed.

Thanks,
Nikhil

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.