A long-standing problem (I'll list a few existing issues outlining these) is that if the logical property (and matching field):
- Starts with capitalized letter (like
"Phone"
) OR - 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
- If
Field
or Creator parameter exists for name with first and/or second letter is capital-case - But said Field/CreatorParameter does not match any setter/getter
- If so, loop through Getter/Setter properties (with no Field/CreatorParameter) and see if case-insensitive match works
- 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.