chad martin
chad martin

Reputation: 31

Dozer NullPointerException on deep-mapping with custom getter

Im getting this exception:

Field mapping error -->
MapId: null
Type: null
Source parent class: com.ParentObject
Source field name: field1
Source field type: class com.OnOff1BitEnum
Source field value: OFF
Dest parent class: com.SubParent
Dest field name: subParent.field2
Dest field type: java.lang.Boolean java.lang.NullPointerException
at org.dozer.util.ReflectionUtils.invoke(ReflectionUtils.java:270)
at org.dozer.propertydescriptor.GetterSetterPropertyDescriptor.getDeepSrcFieldValue(GetterSetterPropertyDescriptor.java:116)
at org.dozer.propertydescriptor.GetterSetterPropertyDescriptor.getPropertyValue(GetterSetterPropertyDescriptor.java:69)
at org.dozer.fieldmap.FieldMap.getDestValue(FieldMap.java:141)

This is the mapping field:

<mapping>
    <class-a>com.ParentObject</class-a>
    <class-b>com.SubParent</class-b>

    <field custom-converter="com.OnOffEnumToBooleanConverter">
        <a>field1</a> 
        <b get-method="isField2">subParent.field2</b> 
    </field>
</mapping>

The version of dozer i am using is 5.4.0

UPDATE: Added the converter code to this post. When i put a break point here this is not being reached

public class OnOffEnumToBooleanConverter implements org.dozer.CustomConverter {
/**
 * {@inheritDoc}
 */
@Override
public Object convert(Object dest, Object src, Class<?> destClass, Class<?> srcClass) {
    if (src == null) {
        return null;
    }
            if (src instanceof com.OnOff1BitEnum) {
        boolean canonicalObject;
        if ((com.OnOff1BitEnum) src == com.OnOff1BitEnum.ON) {
            canonicalObject = true;
        } else if ((com.OnOff1BitEnum) src == com.OnOff1BitEnum.OFF) {
            canonicalObject = false;
        } else { // Unreachable Code To Test
            throw new MappingException("Converter " + this.getClass().getCanonicalName() + " used incorrectly.  Arguments passed in were: "
                    + dest + " and " + src);
        }
        return canonicalObject;
    } 
}

Upvotes: 1

Views: 3347

Answers (1)

user1697575
user1697575

Reputation: 2848

Perhaps it happens because you are missing "set configuration", try specifying it explicitly and see if that solves it or a different error happens, e.g.

<field custom-converter="com.OnOffEnumToBooleanConverter">
        <a>field1</a> 
        <b get-method="isField2" set-method="field2">subParent.field2</b> 
</field>

UPDATE:

I had to properly format your java code to be able to read...here is the problem you have "if and else" for a boolean value...there is no 3rd condition...just carefully look at it:

if (src instanceof com.OnOff1BitEnum)
{
  boolean canonicalObject;
  if ((com.OnOff1BitEnum) src == com.OnOff1BitEnum.ON)
  {
    canonicalObject = true;
  }
  else
  {
    if ((com.OnOff1BitEnum) src == com.OnOff1BitEnum.OFF)
    {
      canonicalObject = false;
    }
    else
    { // Unreachable Code To Test
      throw new MappingException("Converter " + this.getClass().getCanonicalName()
          + " used incorrectly.  Arguments passed in were: " + dest + " and " + src);
    }
  }
  return canonicalObject;
}

That's the evil of "if else construct" that has no brackets in your original code. Also your "convert" method returns Object...so your "boolean canonicalObject" has to be "Boolean canonicalObject" not primitive type.

Should be:

@Override
public Object convert(Object dest, Object src, Class<?> destClass, Class<?> srcClass) 
{    
    if (src instanceof com.OnOff1BitEnum)
    {
      if ((com.OnOff1BitEnum) src == com.OnOff1BitEnum.ON)
      {
        return Boolean.TRUE;
      }
      else
      {
        return Boolean.FALSE;
      }
    }
    return null;
}

Upvotes: 1

Related Questions