Skip to content

R2dbcEntityTemplate.upsert() generates invalid SQL for entities with @Embedded.Empty composite primary keys #2313

Description

@czp3009

Summary

R2dbcEntityTemplate.upsert() generates an invalid DO UPDATE SET clause when the entity uses @Embedded.Empty for a composite primary key. The Kotlin property name of the embedded field (e.g. id) leaks into the SQL as a column name, even though it is not a real database column. PostgreSQL rejects the query with column excluded.id does not exist.

Steps to Reproduce

  1. Define an entity with a composite primary key via @Id @Embedded.Empty:
@Table("entity")
data class Entity(
    @Id @Embedded.Empty
    val id: EntityId,
    val name: String,
) {
    data class EntityId(val col1: String, val col2: String)
}
  1. Corresponding table:
CREATE TABLE entity (
    col1  VARCHAR(255) NOT NULL,
    col2  VARCHAR(255) NOT NULL,
    name  VARCHAR(255) NOT NULL,
    PRIMARY KEY (col1, col2)
)
  1. Call template.upsert(entity)

Expected Behavior

INSERT INTO "entity" ("col1", "col2", "name")
VALUES ($1, $2, $3)
ON CONFLICT ("col1", "col2")
DO UPDATE SET "name" = EXCLUDED."name"

Only non-PK columns appear in DO UPDATE SET.

Actual Behavior

INSERT INTO "entity" ("col1", "col2", "name")
VALUES ($1, $2, $3)
ON CONFLICT ("col1", "col2")
DO UPDATE SET "id" = EXCLUDED."id", "name" = EXCLUDED."name"

PostgreSQL error:

column excluded.id does not exist

The embedded property name id is included in DO UPDATE SET, but id is not a real database column — the actual PK columns are col1 and col2.

Minimal Reproduction

https://github.com/czp3009/r2dbc-upsert-embedded-key-issue-reproduction

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions