FasterXML / FasterXML/jackson-modules-base

Jackson XmlElementWrapper handling with USE_WRAPPER_NAME_AS_PROPERTY_NAME fails if have 2 fields using same XmlElement name/class

Open
#47 0 comments 0 reactions 0 assignees View on GitHub
jaxb-annotations
Dominant language
Java
Stars
180
Forks
80
Avg merge
3h 26m
Merged PRs (30d)
1

Description

Encountered a problem updating from org.codehaus.jackson 1.9.2.
We use name value from XmlElementWrapper rather than the name from XmlElement as the JSON property name for an element. In some cases, we have 2 fields which wrap lists of the same objects. This breaks with current code, because there is an intermediate stage where the code still uses the name from XmlElement (see `JaxbAnnotationIntrospector.findJaxbPropertyName`) even though `MapperFeature.USE_WRAPPER_NAME_AS_PROPERTY_NAME` is set.

```
package com.fasterxml.jackson.module.jaxb.misc;

import java.util.*;

import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;

import com.fasterxml.jackson.databind.MapperFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.module.jaxb.BaseJaxbTest;

/**
* Unit tests to verify handling of @XmlElementWrapper annotation.
*/
public class XmlElementWrapperTest extends BaseJaxbTest
{
static class HasTwoFieldsWithSameElementName {
@XmlElementWrapper(name = "keep")
@XmlElement(name = "value")
public List keepList = Arrays.asList(1,2);

@XmlElementWrapper(name = "purge")
@XmlElement(name = "value")
public List purgeList = Arrays.asList(3,4);

public HasTwoFieldsWithSameElementName() { }

public HasTwoFieldsWithSameElementName(
List keep, List purge) {
keepList = keep;
purgeList = purge;
}

public List getKeepList() {
return keepList;
}

public List getPurgeList() {
return purgeList;
}
}

/** tests that if using wrapper name as property name, this works
* even if 2 fields use the same element name with the same class
*/
public void testWrapperWith2Collections() throws Exception
{
ObjectMapper mapper = getJaxbMapperBuilder()
.enable(MapperFeature.USE_WRAPPER_NAME_AS_PROPERTY_NAME)
.build();
HasTwoFieldsWithSameElementName obj =
new HasTwoFieldsWithSameElementName(Arrays.asList(1, 2),
Arrays.asList(3, 4));

String json = mapper.writeValueAsString(obj);
System.out.println("JSON == "+json);

assertEquals("{\"keep\":[1,2],\"purge\":[3,4]}", json);
HasTwoFieldsWithSameElementName result =
mapper.readValue(json, HasTwoFieldsWithSameElementName.class);
assertNotNull("keepList", result.keepList);
assertEquals("keepList size", 2, result.keepList.size());
assertEquals("keepList first entry", 1, result.keepList.iterator().next().intValue());
}
}
```

Running this test gives:
```
Tests run: 1, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 0.008 sec <<< FAILURE! - in com.fasterxml.jackson.module.jaxb.misc.XmlElementWrapperTest
testWrapperWith2Collections(com.fasterxml.jackson.module.jaxb.misc.XmlElementWrapperTest) Time elapsed: 0.008 sec <<< ERROR!
com.fasterxml.jackson.databind.JsonMappingException: Conflicting getter definitions for property "value": com.fasterxml.jackson.module.jaxb.misc.XmlElementWrapperTest$HasTwoFieldsWithSameElementName#getKeepList(0 params) vs com.fasterxml.jackson.module.jaxb.misc.XmlElementWrapperTest$HasTwoFieldsWithSameElementName#getPurgeList(0 params)
at com.fasterxml.jackson.databind.introspect.POJOPropertyBuilder.getGetter(POJOPropertyBuilder.java:427)
at com.fasterxml.jackson.databind.introspect.BeanPropertyDefinition.getAccessor(BeanPropertyDefinition.java:181)
at com.fasterxml.jackson.databind.introspect.POJOPropertyBuilder.getPrimaryMember(POJOPropertyBuilder.java:563)
at com.fasterxml.jackson.databind.introspect.POJOPropertiesCollector._renameWithWrappers(POJOPropertiesCollector.java:864)
at com.fasterxml.jackson.databind.introspect.POJOPropertiesCollector.collectAll(POJOPropertiesCollector.java:322)
at com.fasterxml.jackson.databind.introspect.POJOPropertiesCollector.getJsonValueAccessor(POJOPropertiesCollector.java:175)
at com.fasterxml.jackson.databind.introspect.BasicBeanDescription.findJsonValueAccessor(BasicBeanDescription.java:236)
at com.fasterxml.jackson.databind.ser.BasicSerializerFactory.findSerializerByAnnotations(BasicSerializerFactory.java:322)
at com.fasterxml.jackson.databind.ser.BeanSerializerFactory._createSerializer2(BeanSerializerFactory.java:207)
at com.fasterxml.jackson.databind.ser.BeanSerializerFactory.createSerializer(BeanSerializerFactory.java:169)
at com.fasterxml.jackson.databind.SerializerProvider._createAndCacheUntypedSerializer(SerializerProvider.java:839)
at com.fasterxml.jackson.databind.SerializerProvider.findValueSerializer(SerializerProvider.java:639)
at com.fasterxml.jackson.databind.SerializerProvider.findTypedValueSerializer(SerializerProvider.java:469)
at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider.serializeValue(DefaultSerializerProvider.java:231)
at com.fasterxml.jackson.databind.ObjectMapper._configAndWriteValue(ObjectMapper.java:1771)
at com.fasterxml.jackson.databind.ObjectMapper.writeValueAsString(ObjectMapper.java:1723)
at com.fasterxml.jackson.module.jaxb.misc.XmlElementWrapperTest.testWrapperWith2Collections(XmlElementWrapperTest.java:55)
```

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.