Skip to content

Honor PropertyNamingStrategy for get/is-prefixed property names#5192

Open
seonwooj0810 wants to merge 1 commit into
swagger-api:masterfrom
seonwooj0810:fix/snakecase-naming-strategy-is-prefix
Open

Honor PropertyNamingStrategy for get/is-prefixed property names#5192
seonwooj0810 wants to merge 1 commit into
swagger-api:masterfrom
seonwooj0810:fix/snakecase-naming-strategy-is-prefix

Conversation

@seonwooj0810

Copy link
Copy Markdown

Description

When a custom PropertyNamingStrategy (e.g. SNAKE_CASE) is configured on the mapper, ModelResolver produced inconsistent schema property names: most fields were translated, but any property whose member name starts with a get/is prefix followed by a lower-case letter kept its original camelCase name.

Example (SNAKE_CASE, Java record):

public record PidLookupResponse(
    String familyName, String expiryDate,
    String issuanceDate, String issuingCountry, String issuingAuthority) {}

Produced:

family_name, expiry_date, issuanceDate, issuingCountry, issuingAuthority

instead of the expected issuance_date, issuing_country, issuing_authority.

Root cause

The "avoid clobbering properties with get/is names" hack (added for #415) overwrites the Jackson-resolved property name with the raw member name whenever the member name starts with get/is + lower-case. For record components the accessor's physical name is the bare component name (issuanceDate), which starts with is, so the hack replaced the strategy-translated issuance_date with issuanceDate.

Fix

Only apply the hack when no PropertyNamingStrategy is configured. When a strategy is active the resolved name is authoritative and must be honored uniformly. The hack was only ever needed to restore raw names in the absence of a strategy:

Both existing test cases continue to pass.

This bug surfaces through springdoc and was traced to swagger-core: springdoc/springdoc-openapi#3293.

Type of Change

  • 🐛 Bug fix
  • 🧪 Tests

Checklist

  • I have added/updated tests as needed
  • The PR title is descriptive
  • The code builds and passes tests locally
  • I have linked related issues

Test evidence

Added RecordPropertyNamingStrategyTest (in swagger-java17-support, which compiles at Java 17 for records). It fails on master (issuanceDate not translated) and passes with this change.

Verification done: reproduced on master; ran the full test suites for swagger-core, swagger-jaxrs2 (incl. ReaderTest#testModelResolverXMLPropertiesName for #2635) and swagger-java17-support — all green (BUILD SUCCESS).

The "avoid clobbering get/is names" hack in ModelResolver replaced the
Jackson-resolved property name with the raw member name for any member
whose name starts with a get/is prefix followed by a lower-case letter.
When a custom PropertyNamingStrategy (e.g. SNAKE_CASE) was configured,
this clobbered the translated name: record components such as
issuanceDate were emitted as "issuanceDate" instead of "issuance_date",
while sibling fields like familyName were correctly translated.

Only apply the hack when no PropertyNamingStrategy is configured, so the
strategy is honored uniformly. The original swagger-api#415 (Scala is_persistent)
and swagger-api#2635 (JAXB-renamed is-prefixed fields) behavior is preserved, as
neither configures a naming strategy.

Reported in springdoc/springdoc-openapi#3293.

Signed-off-by: seonwoo_jung <79202163+seonwooj0810@users.noreply.github.com>
@ewaostrowska ewaostrowska added the backlog label Jun 11, 2026 — with Claude
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants