Search code examples
javaconvertersmapperorika

Orika: How to map using a nested mapper


Consider the following situation:

public class A {

    private ClassInA classInA;

    public ClassInA getClassInA() {
        return classInA;
    }

    public void setClassInA(ClassInA classInA) {
        this.classInA = classInA;
    }

}

public class B {

    private ClassInB classInB;

    public ClassInB getClassInB() {
        return classInB;
    }

    public void setClassInB(ClassInB classInB) {
        this.classInB = classInB;
    }

}

public class ClassInA {

    private String myString;

    public String getMyString() {
        return myString;
    }

    public void setMyString(String myString) {
        this.myString = myString;
    }

}

public class ClassInB {

    private String myString;

    public String getMyString() {
        return myString;
    }

    public void setMyString(String myString) {
        this.myString = myString;
    }

}

Now I want to map A to B using orika. I need a converter to do so. Like:

public class MyMapper {

    @Override
    protected void configure(MapperFactory factory) {
        ConverterFactory converterFactory = factory.getConverterFactory();
        converterFactory.registerConverter(new MyConverter());

        factory.classMap(A.class, B.class) //
                .field("classInA", "classInB") //
                .register();
    }
}

public class MyConverter extends CustomConverter<ClassInA, ClassInB> {

    @Override
    public ClassInB convert(ClassInA source, Type<? extends ClassInB> destinationType) {
        ClassInB classInB = new ClassInB();
        classInB.setMyString(source.getMyString());
        return classInB;
    }

}

Although a mapper for ClassInA to ClassInB would be better. Like:

public class MyMapper extends ConfigurableMapper {

    @Override
    protected void configure(MapperFactory factory) {
        factory.classMap(ClassInA.class, ClassInB.class) //
                .byDefault
                .register();
    }
}

Sadly I have no clue how to register the mapper in MyMapper. There is nothing like converterFactory.registerMapper(new MyMapper());. The only way I could do this is via

.customize(
    return new CustomMapper<LoanContractRequestValue, LoanContrReqERPCrteReqLoanContr>() {
        @Override
        public void mapAtoB(A source, B destination, MappingContext context) {
            destination.setMyString(source.getMyString());
        }
    };
)

But is this really the way to go for?


Solution

  • You can register multiple classMaps in the same mapperFactory, Orika will know which one to use based on the class/type.

    public class MyMapper extends ConfigurableMapper {
        @Override
        protected void configure(MapperFactory factory) {
            factory.classMap(A.class, B.class)
                    .field("classInA", "classInB")
                    .register();
    
            factory.classMap(ClassInA.class, ClassInB.class)
                    .byDefault
                    .register();
        }
    }