Search code examples
javadozer

Dozer 5.4 setCustomConverter does not work between fields of the same name but different types


I want to do custom type conversion with Dozer between fields with the same name but different types in source and destination objects. I prepared code snippet that explains my intention:

package com;

import org.dozer.CustomConverter;
import org.dozer.DozerBeanMapper;
import org.dozer.DozerConverter;

import java.util.Arrays;

public class DozerTest
{
    public static void main(String[] args)
    {
        DozerBeanMapper mapper = new DozerBeanMapper();

        mapper.setCustomConverters(Arrays.<CustomConverter>asList(new DozerConverter<Version, String>(Version.class, String.class)
                {
                    @Override public String convertTo(Version version, String versionOrig)
                    {
                        return version.getFullVersion();
                    }

                    @Override public Version convertFrom(String version, Version versionOrig)
                    {
                        return new Version(version);
                    }
                }));

        OldPackage oldPackage = new OldPackage();

        oldPackage.setVersion("1.1");

        NewPackage newPackage = mapper.map(oldPackage, NewPackage.class);
        System.out.println(newPackage.getVersion().getFullVersion());
    }

    public static class NewPackage
    {
        private Version version;

        public Version getVersion()
        {
            return version;
        }

        public void setVersion(Version version)
        {
            this.version = version;
        }
    }

    public static class OldPackage
    {
        private String version;

        public String getVersion()
        {
            return version;
        }

        public void setVersion(String version)
        {
            this.version = version;
        }
    }

    private static class Version
    {
        private final String fullVersion;

        private Version(String fullVersion)
        {
            this.fullVersion = fullVersion;
        }

        public String getFullVersion()
        {
            return fullVersion;
        }
    }
}

I receive this error message:

Exception in thread "main" org.dozer.MappingException: Illegal object type for the method 'setVersion'. 
 Expected types: 
com.DozerTest$Version
 Actual types: 
java.lang.String

Anyone has an idea what I am doing wrong?


Solution

  • Ik think you forgot to add your mapping to the mapper:

    BeanMappingBuilder foo = new BeanMappingBuilder() {
    
            @Override
            protected void configure() {
                mapping(OldPackage.class, NewPackage.class).fields("version", "version", FieldsMappingOptions.customConverter(ConverterImpl.class));
            }
        };
    mapper.addMapping(foo);
    

    I created a static inner class to represent your DozerConverter implementation to refer it in your BeanMappingBuilder:

    static class ConverterImpl extends DozerConverter<Version, String> {
    
        ConverterImpl() {
            super(Version.class, String.class);
        }
    
        @Override public String convertTo(Version version, String versionOrig)
        {
            return version.getFullVersion();
        }
    
        @Override public Version convertFrom(String version, Version versionOrig)
        {
            return new Version(version);
        }
    }
    

    The full class:

    import org.dozer.CustomConverter;
    import org.dozer.DozerBeanMapper;
    import org.dozer.DozerConverter;
    import org.dozer.loader.api.BeanMappingBuilder;
    import org.dozer.loader.api.FieldsMappingOptions;
    import java.util.Collections;
    
    public class DozerTest
    {
       public static void main(String[] args)
       {
        DozerBeanMapper mapper = new DozerBeanMapper();
    
        mapper.setCustomConverters(Collections.<CustomConverter>singletonList(new ConverterImpl()));
    
        BeanMappingBuilder foo = new BeanMappingBuilder() {
    
            @Override
            protected void configure() {
                mapping(OldPackage.class, NewPackage.class).fields("version", "version", FieldsMappingOptions.customConverter(ConverterImpl.class));
            }
        };
        mapper.addMapping(foo);
    
        OldPackage oldPackage = new OldPackage();
    
        oldPackage.setVersion("1.1");
    
        NewPackage newPackage = mapper.map(oldPackage, NewPackage.class);
        System.out.println(newPackage.getVersion().getFullVersion());
    }
    
    static class ConverterImpl extends DozerConverter<Version, String> {
    
        ConverterImpl() {
            super(Version.class, String.class);
        }
    
        @Override public String convertTo(Version version, String versionOrig)
        {
            return version.getFullVersion();
        }
    
        @Override public Version convertFrom(String version, Version versionOrig)
        {
            return new Version(version);
        }
    }
    
    public static class NewPackage
    {
        private Version version;
    
        public Version getVersion()
        {
            return version;
        }
    
        public void setVersion(Version version)
        {
            this.version = version;
        }
    }
    
    public static class OldPackage
    {
        private String version;
    
        public String getVersion()
        {
            return version;
        }
    
        public void setVersion(String version)
        {
            this.version = version;
        }
    }
    
    private static class Version
    {
        private final String fullVersion;
    
        private Version(String fullVersion)
        {
            this.fullVersion = fullVersion;
        }
    
        public String getFullVersion()
        {
            return fullVersion;
        }
    }
    

    }

    When executing this test class, you get the desired output:

    13:56:34.994 [main] DEBUG org.dozer.MappingProcessor - MAPPED: DozerTest$OldPackage.version --> DozerTest$NewPackage.version VALUES: 1.1 --> be.smals.safe.centralplatform.core.utils.DozerTest$Version@1490eb5 MAPID: 1.1