PropertyNamingStrategy.UPPER_CAMEL_CASE doesn't work as expected when a property name should start with more than one uppercase letter (e.g. BADNamingStrategy) and the corresponding attribute is _private_ (which means that the property name is derived from the getter method)
The following test demonstrates that issue.
package org.me.jackson;
import static org.hamcrest.MatcherAssert.*;
import static org.hamcrest.CoreMatchers.*;
import org.junit.Test;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.PropertyNamingStrategy;
public class JacksonUpperCaseSerializationTest {
ObjectMapper om = new ObjectMapper()
.setPropertyNamingStrategy(PropertyNamingStrategy.UPPER_CAMEL_CASE);
public static class Entity {
// expected property name: BADPublicName
public boolean bADPublicName = true;
// expected property name: BADPrivateName, actual: BadprivateName
private boolean privatePropertyNameDoesntMatter = true;
public boolean getBADPrivateName() {
return privatePropertyNameDoesntMatter;
}
public void setBADPrivateName(boolean bADPrivateName) {
this.privatePropertyNameDoesntMatter = bADPrivateName;
}
}
@Test
public void testSerialization() throws Exception {
final String json = om.writeValueAsString(new Entity());
assertThat(json, containsString("BADPublicName"));
// this one fails: it contains BadprivateName instead
assertThat(json, containsString("BADPrivateName"));
}
@Test
public void testDeserialization() throws Exception {
final String json = "{\"BADPublicName\":false,\"BADPrivateName\":false}";
// here it says that it has only (2 known properties: "BADPublicName", "BadprivateName"])
final Entity entity = om.readValue(json, Entity.class);
assertThat(entity.bADPublicName, is(false));
assertThat(entity.getBADPrivateName(), is(false));
}
}
This is related to the version 2.8.9
I don't think private field should have any effect here since it is not associated with getter/setter name, as far as I can see. Those names must link for any association.
But other than that, code looks like it should work.
... and when I try it, tests pass for me.
Hmmh. Odd. Test passed with master (for 3.0.0-SNAPSHOT) but not with 2.9 branch, and likely also fails with 2.8.
Ahhh. This is actually due to one minor (usually) deviation Jackson has from Bean naming: if multiple leading letters are upper-case, Jackson lower-cases them all (by default), so "BADxxx" becomes "badxxx". But upper case strategy only upper-cases the first letter, leading to problem here.
This behavior can be changed by:
mapper.enable(MapperFeature.USE_STD_BEAN_NAMING)
which is disabled by default; doing this will solve the problem.
And 3.0.0 has this behavior as default (2.x does not just for backwards compatibility).
So, you need to enable this feature.
Most helpful comment
Ahhh. This is actually due to one minor (usually) deviation Jackson has from Bean naming: if multiple leading letters are upper-case, Jackson lower-cases them all (by default), so "BADxxx" becomes "badxxx". But upper case strategy only upper-cases the first letter, leading to problem here.
This behavior can be changed by:
which is disabled by default; doing this will solve the problem.
And 3.0.0 has this behavior as default (2.x does not just for backwards compatibility).
So, you need to enable this feature.