Skip to content

Composite PK that includes Foreign key in ManyToOne fails when updating #10450

@jmc420

Description

@jmc420

Issue description

Composite PK that includes Foreign key in ManyToOne fails when updating

Expected Behavior

When you update a parent entity that has a child with a composite primary key that includes the foreign key to the parent, you would expect Typeorm to save the updated children but instead you get an error.

When you update a parent entity that has a child with a single primary key or a composite primary key that does not include the foreign key, Typeorm updates work fine.

This appears to be related to these issues:

#6416
#4969
#4122

There is a previous fix here:

#6417

Actual Behavior

There are 3 Child entities that have Many To One relations with 3 Parent entities. Child1 has a single primary key and the update works fine. Child3 has a Composite Primary key that does not include the foreign key to Parent3 and it works fine. Child2 is the one with the Composite Primary key that contains a Foreign key to Parent2 and the update fails.

The full set of Entities can be found here: https://github.com/jmc420/typeorm_examples/blob/main/src/server/Entities.ts

Below are the 3 Child entities.

@Entity("child1")
export class Child1Entity {
	@PrimaryGeneratedColumn()
	@Column({ type: "integer", primary: true, nullable: false })
	id?: number;

	@Column({ type: "text", nullable: false })
	name: string;

	@ManyToOne(() => Parent1Entity, (parent1) => parent1.children, { nullable: false, onDelete: 'CASCADE' })
	@JoinColumn([
		{ name: "parent1", referencedColumnName: "id" }
	])
	parent1: Parent1Entity;
}

@Entity("child2")
export class Child2Entity {
	@Column({ type: "text", nullable: false })
	name: string;

	@PrimaryColumn()
	@Column({ type: "integer", primary: true, nullable: false })
	position: number;

	@PrimaryColumn()
	@ManyToOne(() => Parent2Entity, (parent2) => parent2.children, { nullable: false, onDelete: 'CASCADE' })
	@JoinColumn([
		{ name: "parent2", referencedColumnName: "id" }
	])
	parent2: Parent2Entity;
}

@Entity("child3")
export class Child3Entity {
	@PrimaryGeneratedColumn()
	@Column({ type: "integer", primary: true, nullable: false })
	id?: number;

	@Column({ type: "text", nullable: false })
	name: string;

	@PrimaryColumn()
	@Column({ type: "integer", primary: true, nullable: false })
	position: number;

	@ManyToOne(() => Parent3Entity, (parent3) => parent3.children, { nullable: false, onDelete: 'CASCADE' })
	@JoinColumn([
		{ name: "parent3", referencedColumnName: "id" }
	])
	parent3: Parent3Entity;
}

When you update the Parent2 entity that references Child2 which has the composite primary key that includes a foreign key, Typeorm throws an error.

In a postgres environment, the error is "duplicate key value violates unique constraint "PK_865f162bd45f88ff770ed28f518"

In a mySQL environment, the error is Duplicate entry for key 'PRIMARY'

Steps to reproduce

An example with the error can be found here: https://github.com/jmc420/typeorm_examples

Check out the code, run npm i and create a postgres database where the credentials match the DataSource in ./src/testTest.spec.ts

Compile with npm run compile

Run the test with npm run test

My Environment

Dependency Version
Operating System OSX Monterey
Node.js version 18.17.1
Typescript version 5.1.6
TypeORM version 0.3.17

Additional Context

No response

Relevant Database Driver(s)

  • aurora-mysql
  • aurora-postgres
  • better-sqlite3
  • cockroachdb
  • cordova
  • expo
  • mongodb
  • mysql
  • nativescript
  • oracle
  • postgres
  • react-native
  • sap
  • spanner
  • sqlite
  • sqlite-abstract
  • sqljs
  • sqlserver

Are you willing to resolve this issue by submitting a Pull Request?

No, I don’t have the time and I’m okay to wait for the community / maintainers to resolve this issue.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions