Skip to content

Exclude composite identifier columns from the UPDATE SET clause - #2407

Open
sharanggupta wants to merge 1 commit into
spring-projects:mainfrom
sharanggupta:gh-2338-embedded-id-columns-in-update
Open

sharanggupta wants to merge 1 commit into
spring-projects:mainfrom
sharanggupta:gh-2338-embedded-id-columns-in-update

Conversation

@sharanggupta

Copy link
Copy Markdown
  • You have read the Spring Data contribution guidelines.
  • You use the code formatters provided here and have them applied to your changes. Don’t submit any formatting related changes.
  • You submit test cases (unit or integration tests) that back your changes.
  • You added yourself as author in the headers of the classes you touched. Amend the date range in the Apache license header if needed. For new types, add the license header (copy from another file and set the current year only).

Closes #2338

For an aggregate whose @Id is a composite identifier, SqlGenerator.Columns classified the identifier's columns as regular columns because it asked the property's owner (the identifier type itself, which has no @Id of its own) whether the property is the id. The columns consequently appeared in the SET clause of the generated UPDATE in addition to the WHERE clause, which fails on databases that reject assignments to primary key columns (the YDB dialect currently works around this downstream in ydb-platform/ydb-java-dialects#241).

The column walk now carries the attributes a property inherits from its enclosing properties (column prefix, insert-only, part of the identifier) in one small Nesting value instead of two parallel parameters, so columns reached through the @Id property are registered as identifier columns and excluded from SET. WHERE and INSERT are unchanged; the latter already receives the identifier columns from the parameter source. If you would rather keep the existing parameter style and just thread an additional flag, I am happy to change it.

Unit tests cover both declaration forms (@Id EmployeeId id in SqlGeneratorUnitTests, @Id @Embedded EmbeddedId in SqlGeneratorEmbeddedUnitTests); both fail on main. The spring-data-jdbc unit suite (590 tests) and the HSQL composite-id and embedded integration tests pass.

The column cache in SqlGenerator.Columns decided whether a column belongs to the identifier by asking the property's owner. For a composite identifier the owner of each column is the identifier type itself, which carries no @id annotation of its own, so every column of the composite identifier was classified as a regular column and ended up in the SET clause of the generated UPDATE statement in addition to the WHERE clause. Databases that reject assignments to primary key columns fail the statement, which makes save() unusable for aggregates with a composite identifier.

The traversal of embedded entities now carries the attributes a property inherits from the properties enclosing it, namely the column prefix, whether it is reached through an insert-only property and whether it is part of the identifier, in a single Nesting value. Columns reached through the @id property are registered as identifier columns and therefore excluded from the SET clause, while the WHERE clause and the INSERT statement, which already obtain the identifier columns from the parameter source, are unchanged.

Closes spring-projects#2338

Signed-off-by: Sharang Gupta <sharang@sharanggupta.dev>
@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged label Oct 6, 2026

This branch has not been deployed

No deployments
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.

Composite (embedded) @Id columns are not excluded from UPDATE SET clause

2 participants