question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Serialization of constant value creates two entries

See original GitHub issue

Serialization of one constant value creates two entries with different keys.

Steps to reproduce:

Given the following class (including test to reproduce issue):

@DisplayName( "Test constant value serialization" )
class ConstantTest {
   @Data
   class TestPojo {
      @JsonProperty("content-spec")
      private String CONTENT_SPEC = "This wont be changed";
   }

   @Test
   @DisplayName( "should contain content spec" )
   @SneakyThrows
   void shouldContainContentSpec() {
      TestPojo value = new TestPojo();
      String payload = new ObjectMapper().writeValueAsString( value );

      assertThat( payload ).isEqualTo( "{\"content-spec\":\"This wont be changed\"}" );
   }
}

Actual Behaviour

Results in the following output:

{
  "content_SPEC": "This wont be changed",
  "content-spec": "This wont be changed"
}

Note the two key/value pairs and that the word “SPEC” is uppercased while “content” is not.

Expected Behaviour

{
  "content-spec": "This wont be changed"
}

Additional hints:

  • It works as expected when renaming the field to contentSpec.
  • When removing the @JsonProperty annotation, only the content_SPEC key is left.
  • Version 2.9.9.3

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Comments:11 (5 by maintainers)

github_iconTop GitHub Comments

2reactions
cowtowncodercommented, Dec 3, 2019

Thank you for fully documenting the work-around needed in this case; other users will probably find this useful as well!

Some more information just in case it might be useful…

Lower-casing or not of “CONTENT” is actually one aspect that is configurable: default one Jackson uses deviates from standard Bean naming convention I think. Setting to change is:

MapperFeature.USE_STD_BEAN_NAMING

which defaults to false for backwards-compatibility reasons. When enabled, inferred name would remain CONTENT_SPEC (because there is more than one capital letter starting name part), whereas legacy default setting would lower-case the continuous upper-case letter segment, to come up with content_SPEC (underscore ending the segment). It is actually possible to further re-configure aspects of casing with PropertyNamingStrategy, but that is more geared towards different style in JSON, not on POJO method naming.

0reactions
jwedelcommented, Dec 3, 2019

@cowtowncoder It’s a bit weird, that the word “CONTENT” is lower-cased but, OK. So, based on your valuable input, here is the fixed version with lombok (for anyone who is interested):

@DisplayName( "Test constant value serialization" )
class ConstantTest {
   @Data
   @Getter()
   class TestPojo {
      @JsonProperty( "content-spec" )
      @Getter( AccessLevel.NONE )
      @Setter( AccessLevel.NONE )
      private String CONTENT_SPEC = "This wont be changed";
   }

   @Test
   @DisplayName( "should contain content spec" )
   @SneakyThrows
   void shouldContainContentSpec() {
      TestPojo value = new TestPojo();
      String payload = new ObjectMapper().writeValueAsString( value );

      assertThat( payload ).isEqualTo( "{\"content-spec\":\"This wont be changed\"}" );
   }
}

This test actually succeeds. What did I do:

  • I disabled getter/setter generation for the constant value. Obviously, it doesn’t make sense to annotate the class with @Data but usually, you have more fields that also requires to have getter/setter.

Now, there is no getter for CONTENT_SPEC and jackson will only pickup the @JsonProperty annotation and correctly serialize it.

Read more comments on GitHub >

github_iconTop Results From Across the Web

C# - Serialize Constants with DataContractJsonSerializer
const is a special keyword in .NET. If you specify field as constant, it would not exist ...
Read more >
Java Object Serialization Specification: 1 - System Architecture
The serialized form of an enum constant consists solely of its name; field values of the constant are not present in the form....
Read more >
Class Serialization Traits - Boost C++ Libraries
This means that class instances are tracked only if they are serialized through pointers anywhere in the program. Now multiple saves from the...
Read more >
Examples of XML Serialization | Microsoft Learn
If two items are ordered, the serialized class instance might look ... It just creates objects to deserialize and reads out their values....
Read more >
Serialization Guide - Json.NET
JObject will be created for JSON objects; JArray will be created for JSON arrays, and JValue will be created for primitive JSON values....
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found