Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to configure Orika to map a class to another depending on a context?

Tags:

java

orika

I am trying to migrate a project that use dozer to orika.

In dozer, it's a common practice to have something like that :

<?xml version="1.0" encoding="UTF-8"?>
<mappings xmlns="http://dozer.sourceforge.net" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://dozer.sourceforge.net
http://dozer.sourceforge.net/schema/beanmapping.xsd">
    <mapping map-id="all">
        <class-a>com.bnppa.cdj.dto.Source</class-a>
        <class-b>com.bnppa.cdj.dto.Destination</class-b>
        <field>
            <a>id</a>
            <b>id</b>
        </field>
        <field>
            <a>someField</a>
            <b>someField</b>
        </field>
    </mapping>

    <mapping map-id="small">
        <class-a>com.bnppa.cdj.dto.Source</class-a>
        <class-b>com.bnppa.cdj.dto.Destination</class-b>
        <field>
            <a>id</a>
            <b>id</b>
        </field>
    </mapping>
</mappings>

And then use the mapId when converting the object :

Source s = ...

List<String> mappingFiles = new ArrayList<String>();
mappingFiles.add("dozer/dozerMapping.xml");
mapper = new DozerBeanMapper(mappingFiles);

Destination d = mapper.map(mySource, Destination.class, "small");

So my question is : How to configure Orika to have the such mapId things ?

I can't find how to declare a map-id when I define my mappers :

MapperFactory factory = new DefaultMapperFactory.Builder().build();

//Register a mapper
factory.registerClassMap(factory.classMap(Source.class, Destination.class)
        .field("id","id")
        .field("someField", "someField")
        .toClassMap());
like image 863
fluminis Avatar asked Jun 13 '13 08:06

fluminis


2 Answers

The quick answer : there is no built-in support for this feature.

But for a good reason, basically because usually different context means the need to create different classes (well defined responsibility). The second point is within a deep graph of objects Orika reuse the same definitions of class-map. So the context may not depend on cases of class-map but on larger basis graph-map.

When you have serious use-case beyond the simple "reuse" of the same class or some well defined scenarios, I will suggest you to use a dedicated MapperFactory per scenario.

For example when exposing services via a REST API, methods GET (list)/ GET (details) /POST/PUT, you can have for each one, a dedicated Mapper.

IMHO, in the case of Entity and DTO... DTO are contracts a way to give a typed-tuple a name. Have contextualized use of the same class is something that leads to a lot of hidden knowledge around code. Having a specific class for each use-case is a (small but important) step towards good design.

like image 143
Sidi Avatar answered Nov 12 '22 00:11

Sidi


You may want to create multiple MapperFacades in Orika and use appropriate MapperFacade in each case.

Another approach to use custom mappers, in this case you would be able to pass something in mapping context, check this context parameter and perform mapping in your custom mappings according to that flag.

like image 42
Dmitry Zvorygin Avatar answered Nov 12 '22 00:11

Dmitry Zvorygin