Dozer: Mapping of class with no default constructor
Asked Answered
R

4

10

Lets say I want to map the following two classes:

public class A {

    String member;

    public void setMember(String member) { this.member = member }
    public String getMember() { return member }
}

public class B {

    String member;

    public B(String member) { this.member = member }

    public String getMember() { return member }
}

Now when I want Dozer to do the following conversion: dozerBeanMapper.map( a, B.class ); I get an error because of the missing default constructor of class B.

What's the best way to solve that problem? Use a custom converter?

Rhiamon answered 15/11, 2011 at 8:52 Comment(0)
L
9

If class B is not your API and you have no control over it and you intend to map member property anyway, you can get away with a custom bean factory that can perhaps pass a default value to the costructor:

<mapping>
  <class-a>com.example.A</class-a>
  <class-b bean-factory="com.example.factories.BFactory">
    com.example.B
  </class-b>
</mapping>

Your factory will implement org.dozer.BeanFactory interface:

public interface BeanFactory {
  public Object createBean(Object source, Class sourceClass, String targetBeanId);
}
Lockup answered 15/11, 2011 at 9:0 Comment(0)
G
4

From Dozer FAQ:

Some of my data objects don't have public constructors. Does Dozer support this use case?

Yes. When creating a new instance of the destination object if a public no-arg constructor is not found, Dozer will auto detect a private constructor and use that. If the data object does not have a private constructor, you can specify a custom BeanFactory for creating new instances of the destination object.

Here is a documentation of Custom Bean Factories

Gastongastralgia answered 15/11, 2011 at 8:57 Comment(0)
J
3

I ran into this issue while trying to map a java.util.Locale. To solve my problem I did as follows :

I created a class called LocaleMapper which would match dumb LocaleToLocaleConversion

public class LocaleMapper extends DozerConverter<Locale, Locale> {
    public LocaleMapper() {
        super(Locale.class, Locale.class);
    }

    @Override
    public Locale convertTo(Locale localeA, Locale localeB) {
        return localeA;
    }

    @Override
    public Locale convertFrom(Locale localeA, Locale localeB) {
        return localeA;
    }
}

Then I modified the mapping xml of the project :

<converter type="LocaleMapper">
            <class-a>java.util.Locale</class-a>
            <class-b>java.util.Locale</class-b>
 </converter>

Now I can add Locale objects to my classes that are mapped with Dozer. My Dozer knowledge is somewhat limited, so I can't explain the indepth details of how it works underneath the hood, but it worked for my project.

Jataka answered 14/5, 2013 at 18:44 Comment(0)
C
0

You can either create a default constructor for B, or alternatively use a custom BeanFactory, so that Dozer can create the instance it needs.

Clinandrium answered 15/11, 2011 at 9:3 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.