spring-projects / spring-projects/spring-data-relational

Provide a way to alter composite key backreference naming

Open
#2,288 2 comments 3 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

type: enhancement
Dominant language
Java
Stars
827
Forks
394
PR merge metrics
No merged PRs in 30d

Description

Mapping an existing schema like

create table product(
  tenant bigint,
  code text,
  ...
  primary key (tenant, code)
);

create table product_i18n(
  tenant bigint,
  product_code text,
  language text,
  name text,
  description text,
  primary key (tenant, product_code, language),
  foreign key (tenant, product_code) references product(tenant, code)
);
record ProductPK(Long tenant, String code) {}

@Table("product")
record Product(
  @Id ProductPK pk,
  @MappedCollection(keyColumn = "language") Map<String, ProductI18n> localization,
  ...
) {}

@Table("product_i18n")
record ProductI18n(String name, String description) {}

Loading any data expects that the product_i18n.tenant column would be named product_tenant.

Documentation says



All references in an aggregate result in a foreign key relationship in the opposite direction in the database. By default, the name of the foreign key column is the table name of the referencing entity.

If the referenced id is an @Embedded id, the back reference consists of multiple columns, each named by a concatenation of <table-name> + _ + <column-name>. E.g. the back reference to a Person entity, with a composite id with the properties firstName and lastName will consist of the two columns PERSON_FIRST_NAME and PERSON_LAST_NAME.

Alternatively you may choose to have them named by the entity name of the referencing entity ignoring @Table annotations. You activate this behaviour by calling setForeignKeyNaming(ForeignKeyNaming.IGNORE_RENAMING) on the RelationalMappingContext.

I guess the 3rd paragraph is referring to the first and not the second as AggregatePath.java#410 is:

if (idProperty != null && idProperty.isEntity()) {
    RelationalPersistentEntity<?> idEntity = basePath.getRequiredLeafEntity();
    idEntity.doWithProperties((PropertyHandler<RelationalPersistentProperty>) p -> {
        AggregatePath idElementPath = basePath.append(p);
	SqlIdentifier name = idElementPath.getColumnInfo().name();
	name = name.transform(n -> idDefiningParentPath.getTableInfo().qualifiedTableName.getReference() + "_" + n);
	ciBuilder.add(idElementPath, name, name);
    });
} else {

so please provide a way to give the name the columns for composite pks back reference.

Have not tested saving, assuming something similar is an issue there.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reading the composite-id naming branch in AggregatePath.java around line 410 and compare it with the documented ForeignKeyNaming behavior. Reproduce the provided product/product_i18n mapping, then verify that a configurable composite-key backreference naming mechanism works for both loading and saving against the existing schema.

Written by the indexing model from the issue text.

Assessment

Tech stack
java
Domain
backend, database
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.