Skip to content

Honor standalone @Collation on entities and propagate to repository base methods#5218

Open
seonwooj0810 wants to merge 1 commit into
spring-projects:mainfrom
seonwooj0810:fix/issue-4535-collation-annotation
Open

Honor standalone @Collation on entities and propagate to repository base methods#5218
seonwooj0810 wants to merge 1 commit into
spring-projects:mainfrom
seonwooj0810:fix/issue-4535-collation-annotation

Conversation

@seonwooj0810

Copy link
Copy Markdown

What this addresses

@Collation on an entity is not picked up unless it is set through @Document(collation = ...), and even when it is picked up, the entity collation only reaches Example-based repository methods. Plain CRUD methods (findById, findAll, count, deleteAll, …) are dispatched without it, so the resulting MongoDB operation runs with no collation even though the entity declares one.

Closes: #4535

Root cause

Two cooperating gaps in the entity → repository wiring:

  1. BasicMongoPersistentEntity only consults @Document.collation(). The standalone @Collation annotation in org.springframework.data.mongodb.core.annotation is the canonical source (it is what @Document.collation() is itself @AliasFor for), yet it is ignored unless @Document is present and uses the collation attribute. So @Collation(\"en_US\") on a type — with or without an accompanying @Document — silently has no effect.

  2. SimpleMongoRepository / SimpleReactiveMongoRepository only propagate entityInformation.getCollation() on the Example-based query path. The basic CRUD methods (findById, existsById, findAll, findAll(Sort), findAll(Pageable), findAllById, count, deleteById, deleteAllById, deleteAll) build their Query without .collation(...), so even if (1) is fixed, the collation is dropped at the repository boundary.

These are exactly the two locations called out in the issue thread.

Change summary

BasicMongoPersistentEntity — resolve collation via AnnotatedElementUtils.findMergedAnnotation(rawType, Collation.class). Because @Document is meta-annotated with @Collation and Document#collation is declared as @AliasFor(annotation = Collation.class, attribute = \"value\"), the merged lookup returns the same value whether the user writes @Document(collation = \"en_US\") or @Collation(\"en_US\") (with or without @Document). Existing @Document.collation() behavior — literal value, SpEL expression, JSON document form — is preserved.

SimpleMongoRepository and SimpleReactiveMongoRepository — add a small applyDefaultCollation(Query) helper and invoke it from every base CRUD method that builds a Query (and from the shared findAll(Query) / getIdQuery(Iterable) helpers that funnel findAll and findAllById). The helper only sets the collation when one is defined and the query does not already carry one, so an explicit Query.collation(...) from a caller still wins.

Why this is the right fix

The maintainer (christophstrobl) diagnosed exactly this shape on the issue: "BasicPersistentEntity did not properly consider @Collation but was only looking for @Document and the collation was not properly passed on in SimpleMongoRepository." The change is additive — annotation handling extends to a strictly larger set of users (the existing @Document(collation=...) users keep getting the same Collation instance), and collation propagation aligns the base CRUD methods with the Example-based methods that have always carried it. Behavior for users that do not declare an entity collation is unchanged: entityInformation.hasCollation() returns false and applyDefaultCollation is a no-op.

Tests

New tests added:

  • BasicMongoPersistentEntityUnitTests:
    • readsStandaloneCollationAnnotation@Document + standalone @Collation(\"en_US\") resolves to Collation.of(\"en_US\").
    • readsStandaloneCollationAnnotationWithoutDocumentAnnotation@Collation(\"en_US\") without @Document resolves correctly.
  • SimpleMongoRepositoryUnitTests:
    • shouldAddDefaultCollationToFindMethods (parameterized over findAll(), findAll(Sort), findAll(Pageable)).
    • shouldAddDefaultCollationToFindById, shouldAddDefaultCollationToExistsById, shouldAddDefaultCollationToCount, shouldAddDefaultCollationToDeleteById, shouldAddDefaultCollationToDeleteAll.
  • SimpleReactiveMongoRepositoryUnitTests:
    • shouldAddDefaultCollationToFindById, shouldAddDefaultCollationToCount, shouldAddDefaultCollationToDeleteAll.

Existing collation tests (DATAMONGO-1854, DATAMONGO-2565) continue to pass; they cover @Document(collation = ...) literal/JSON/SpEL forms.

Verification done

  • ✅ Reviewed the issue thread and confirmed the maintainer-pinpointed root cause matches the code state on main (BasicMongoPersistentEntity ignores standalone @Collation; SimpleMongoRepository drops collation on base CRUD methods).
  • ✅ Searched gh pr list and PR search on spring-projects/spring-data-mongodb for any in-flight PR referencing @Collation annotation on documents, repositories or queries not interpreted #4535 — none.
  • ✅ Confirmed no "I'm working on this" claim from another contributor in the last 21 days (last comments are user bumps from 2025-03 and 2025-07-19).
  • ✅ Grepped main for BasicMongoPersistentEntity, SimpleMongoRepository, SimpleReactiveMongoRepository, and entityInformation.getCollation() to confirm the bug pattern is still present.
  • ✅ Targeted Maven build: ./mvnw -pl spring-data-mongodb test -Dtest='BasicMongoPersistentEntityUnitTests,SimpleMongoRepositoryUnitTests,SimpleReactiveMongoRepositoryUnitTests' → 61 tests, all green.
  • ✅ Broader regression: ./mvnw -pl spring-data-mongodb test -Dtest='BasicMongoPersistent*,*Mongo*Repository*UnitTests,*MongoQuery*UnitTests' → 365 tests, all green.

Scope notes

The issue also mentions @Collation on the repository interface and on individual query methods. Those flow through MongoQueryMethod (a separate code path from BasicMongoPersistentEntity / SimpleMongoRepository) and were intentionally left out to keep this change focused on the entity-level case the maintainer explicitly confirmed; method-level @Collation already works through the @Query(collation = ...) alias.

…ase methods.

Read the standalone @collation annotation on the entity type from
BasicMongoPersistentEntity. @Document.collation() keeps working through
@aliasfor merging; standalone @collation now contributes the entity collation
even when @document is absent or omits collation.

Propagate the entity collation through SimpleMongoRepository and
SimpleReactiveMongoRepository base CRUD methods (findById, existsById,
findAll, count, deleteById, deleteAll, ...) so the collation is honored
consistently, matching the behavior of Example-based methods.

Closes: spring-projects#4535
@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged label Jun 19, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

status: waiting-for-triage An issue we've not yet triaged

Projects

None yet

Development

Successfully merging this pull request may close these issues.

@Collation annotation on documents, repositories or queries not interpreted

2 participants