A long-standing problem (I'll list a few existing issues outlining these) is that if the logical property (and matching field):

  1. Starts with capitalized letter (like "Phone") OR
  2. Has second letter capitalized (like "iPhone")

then there are no possible "getter"/"setter" methods from which property could be derived. So there is either mismatch or duplication of properties because following won't match:

public class IPhoneBean {
    private String iPhone;

    // These infer property "iphone" as leading capitals are lower-cased
    public String getIPhone() { return iPhone; }
    public void setIPhone(String value) { iPhone = value; }
}

same would happen if field name starts with capital letter(s).

Existing issues:

  • 2696 ("oAuth")

  • 2835 ("dLogHeader")

  • 4093 ("mValue")

Comment From: cowtowncoder

Proposed solution is to add secondary processing for POJOPropertiesCollector (I think) where

  1. If Field or Creator parameter exists for name with first and/or second letter is capital-case
  2. But said Field/CreatorParameter does not match any setter/getter
  3. If so, loop through Getter/Setter properties (with no Field/CreatorParameter) and see if case-insensitive match works
  4. If so, merge the two -- and use Field/CreatorParameter name (over getter/setter variant)

Comment From: JooHyukKim

This could probably be another MapperFeature that disabled in jackson 2 but enabled in 3?

Comment From: cowtowncoder

+1 for MapperFeature. If it's safe enough could consider enabling by default even for 2.20 (and leave ability to disable for unlikely edge cases). But that can be decided on once this gets implemened.

Comment From: JooHyukKim

Ai-generated and personally filtered list of name candidates. One I like is ACCEPT_I_PHONE_STYLE_PROPERTIES for being intitutitve? WDYT

Candidate Intention Alignment with Jackson naming conventions Notes
ALLOW_MIXED_CAPS_PROPERTY_MERGE Allow merging when property names use MixedCaps (e.g., iPhone) Consistent with ALLOW_EXPLICIT_PROPERTY_RENAMING Emphasizes “allow” over “merge”
ACCEPT_IPHONE_STYLE_PROPERTIES Accept property names whose second letter is uppercase Follows ACCEPT_ pattern such as ACCEPT_CASE_INSENSITIVE_ Very explicit about the pattern
UNIFY_MIXED_CAPS_PROPERTIES Unify MixedCaps property variants into one logical property UNIFY is novel but readable alongside USE_* enums Clear but new verb
HANDLE_SECOND_CAP_PROPERTY_VARIANTS Handle variants where the second character is capitalized Few precedents for HANDLE_* prefix Verbose
ALLOW_NON_STD_CAPS_MATCHING Allow matching of non-standard capitalization variants Aligns with other ALLOW_* flags “Matching” sounds weaker than “merge”
COMBINE_CAMEL_CASE_VARIANTS Combine CamelCase variants into a single property No current COMBINE_* enum, but clear intent New prefix
ACCEPT_CAMEL_MIXED_CAPS_PROPERTIES Accept Camel/MixedCaps property variants Similar to ACCEPT_CASE_INSENSITIVE_PROPERTIES

Comment From: k163377

This problem often occurs with Kotlin as well. It would be more useful if other cases could be handled without additional reflection by Kotlin, for example

   private final boolean isFoo;
   private final Boolean isBar;
   private final String baz-baz;

   public final boolean isFoo() {
      return this.isFoo;
   }

   @Nullable
   public final Boolean isBar() {
      return this.isBar;
   }

   @NotNull
   public final String getBaz-baz() {
      return this.baz-baz;
   }

Comment From: cowtowncoder

@k163377 "is-getters" are problematic since Kotlin definition differs from Java beans. But this is bit different from issue I try to describe here.

It might be worth filing separate issue for, outlining exact expectation (I am guessing JSON property Jackson infers is "foo", but Kotlin tools would expect "isFoo" -- but that (or whatever expectation is) needs to be explicitly spelled out).

Comment From: cowtowncoder

@JooHyukKim yeah, with quick look I kind of like "UNIFY_MIXED_CAPS_PROPERTIES". Or could have something along "FIX_LEADING_UPPER_CASE_NAMES" lines.

Comment From: JooHyukKim

@k163377 I don't think baz-baz work as property in Kotlin? Or maybe I am missing something here.

Comment From: k163377

@JooHyukKim In Kotlin, properties can be defined as follows

val `baz-baz`: String

The code shared in the comment is the formatted result of decompiling to Java.

Comment From: cowtowncoder

I don't think we need to support baz-baz (at least not at first), despite it being legal from Kotlin perspective -- it seems ok to require @JsonProperty for now. Unless it turns out easy/possible to support.

Not sure if the approach I have in mind could work, depends on when and how we apply Naming Strategies -- perhpas it does. Although likely single-leading character would be problematic there too, wrt x-ray -> logical "xRay" -> getter "getXRay()" -> mangled as "xray".

Comment From: JooHyukKim

Okay I thought too simply. Makes sense. Modified accordinlgy with tests with correct behavior from my perspective

Comment From: k163377

I don't think we need to support baz-baz (at least not at first)

Yes, even if it is allowed in the JVM, it may not be necessary to actively support it, as it is an impossible case in normal Java.

Comment From: JooHyukKim

Closed by mistake in #5166

Comment From: cowtowncoder

Possible fix via #5187.