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.

Snake case strategy should consider numerics as capital letters

See original GitHub issue

Context: jackson-databind v2.8.7

Problem:

The snake case strategy doesn’t consider numerics may be part of a field name. When a service/json is being consumed that has a number in the name, for example volume_30day [1], the field cannot be matched to the java object model [2] without overriding [3][4] the object mapper.

Expected Behavior

The snake case strategy should consider a numeric in the field name to be a capital letter in the context of the snake case strategy.

Workaround

Handle the specific property translation by extending the SnakeCaseStrategy [3] and initializing it in the object mapper [4]

Appendix

[1] Sample json body

{
  "open": "19442.38000000",
  "high": "19787.99000000",
  "low": "18200.00000000",
  "volume": "28237.41544911",
  "last": "18575.00000000",
  "volume_30day": "952310.05768915"
}

[2] Swagger generated java model

@ApiModel(description="Product 24 hour stats")
public class ProductStats  {
...
  @ApiModelProperty(example = "null", value = "")
  private BigDecimal volume30day = null;
...
 public BigDecimal getVolume30day() {
    return volume30day;
  }
  public void setVolume30day(BigDecimal volume30day) {
    this.volume30day = volume30day;
  }
  public ProductStats volume30day(BigDecimal volume30day) {
    this.volume30day = volume30day;
    return this;
  }

[3] Extended snake case strategy

public class ExtSnakeCaseStrategy extends PropertyNamingStrategy.SnakeCaseStrategy {
    @Override
    public String translate(String input)
    {
        if(input == "volume30day") {
            return "volume_30day";
        }
        return super.translate(input);
    }
}

[4] Object mapper initialization

        ObjectMapper modelMapper = new ObjectMapper();
        modelMapper.setPropertyNamingStrategy(new ExtSnakeCaseStrategy());

Issue Analytics

  • State:closed
  • Created 6 years ago
  • Comments:8 (6 by maintainers)

github_iconTop GitHub Comments

1reaction
cowtowncodercommented, May 12, 2020

I think better definition would be needed: if someone can point to a specification, or set of tests from other systems that do similar mapping, those would be great.

To me, logically there are couple of possibilities if starting from volume_30day:

  • [get]Volume30Day (seems most readable)
  • [get]Volume30day (original suggestion)

but maybe as importantly, Jackson actually starts with “standard” name, extracted from get/set methods. So we could start from [get]Volume30day and I suppose there could be different expected answers there too:

  • volume_30_day
  • volume30day (current result)
  • volume_30day (suggested new result)

All of these are possible to produce I think by simple change in PropertyNamingStrategy.SnakeCaseStrategy (line 319), by replacing:

if (Character.isUpperCase(c))

with

if (Character.isUpperCase(c) || Character.isDigit(c))

but doing so will break existing tests, which assume no changes to cases like “a1” and “A1”.

0reactions
cowtowncodercommented, Nov 20, 2020

@Hronom I’d be open to adding a new strategy, but what is really needed even more than implementation would be test case(s) to show expected behavior. Adding implementation only is problematic because that does not really define how various things should work, just how particular piece of code happens to work.

So: may be reopened (or re-filed) with definition of expected behavior.

Then again, users are free to implement their own naming strategies as well, so it is not clear if a new one should be added as one of default choices.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Camel case vs. snake case: What's the difference? | TechTarget
Camel case and snake case stand at opposite ends of the variable naming convention spectrum. When multiple words are used to form a...
Read more >
Camel Case vs. Snake Case vs. Pascal Case - Khalil Stemmler
To denote a constant, we typically implement screaming snake case: snake case with all of the letters capitalized.
Read more >
Jackson SNAKE_CASE How to generate underscore in field ...
Yes, this is possible using a PropertyNamingStrategy : objectMapper.setPropertyNamingStrategy(PropertyNamingStrategies.SNAKE_CASE).
Read more >
How to set custom CodingKey for the convertFromSnakeCase ...
Swift uses Camel case naming convention, but not all back-end languages use the same convention. Ruby, for example, uses Snake case when ...
Read more >
Camel and Snake Case Converter - Capitalize My Title
This leaves a concatenation of words that is combined into a single string with various letters capitalized throughout. It is typically used by ......
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