Chris311
Chris311

Reputation: 3992

Orika null to List

Consider the 2 objects:

public class ClassA {

    private List<Animal> animals;

    public List<Animal> getAnimals() {
        return animals;
    }

    public void setAnimals(List<Animal> animals) {
        this.animals = animals;
    }

}

public class ClassB {

    private List<OtherAnimals> animals;

    public List<OtherAnimals> getAnimals() {
        return animals;
    }

    public void setAnimals(List<OtherAnimals> animals) {
        this.animals = animals;
    }

}

With orika-mapper:

public class AnimalMapper extends ConfigurableMapper {

    @Override
    protected void configure(MapperFactory factory) {
        factory.classMap(ClassA.class, ClassB.class) //
                .mapNulls(true) //
                .byDefault() //
                .register();
    }

}

Then the following test fails:

@Test
public void testMap() throws Exception {
    ClassA classA = new ClassA();

    ClassB outcome = classUnderTest.map(classA, ClassB.class);

    assertThat(outcome.getAnimal(), is(nullValue()));
}

That is because outcome.getAnimal() has become an empty array list. Why does this happen? The other quite remarkable thing is: If I fill the those 2 lists with content, the mapping even takes place! Although they are of different types!

That is

@Test
public void testMap() throws Exception {
    ClassA classA = new ClassA();
    Animal animal = new Animal();
    animal.setName("Brix");
    classA.setAnimals(Arrays.asList(animal));

    ClassB outcome = classUnderTest.map(classA, ClassB.class);

    assertThat(outcome.getAnimal().get(0).getName(), is("Brix"));
}

with

public class Animal {

    String name;

    public String getName() {
        return name;
    }

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

}

and

public class OtherAnimal {

    String name;
    int age;

    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

}

succeeds. Can one count on that and is this safe?

Upvotes: 0

Views: 1447

Answers (1)

Sidi
Sidi

Reputation: 1739

This happen because Orika will create a mapper on the fly using byDefault settings. And it's actually safe when Orika find fields with same name and compatible types (List of A to Collection of B, Then create another mapper for A to B which seems to have a common field name:String).

If it does not fit your taste you can disable this "magic" using useAutoMapping(boolean useAutoMapping);

http://orika-mapper.github.io/orika-docs/mapper-factory.html

Upvotes: 1

Related Questions