Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

OneToOne relation creates invalid query #11180

Open
1 of 18 tasks
zbposs opened this issue Dec 11, 2024 · 2 comments
Open
1 of 18 tasks

OneToOne relation creates invalid query #11180

zbposs opened this issue Dec 11, 2024 · 2 comments

Comments

@zbposs
Copy link

zbposs commented Dec 11, 2024

Issue description

OneToOne relation creates invalid query

Expected Behavior

Returning Parent with Child

Actual Behavior

Typeorm creates invalid query that throws error:

invalid reference to FROM-clause entry for table "parent"

select
	"Parent"."id" as "Parent_id",
	"Parent__Parent_child"."id" as "Parent__Parent_child_id",
	"Parent__Parent_child"."parent_id" as "Parent__Parent_child_parent_id",
	"Parent__Parent_child"."sub_child_name" as "Parent__Parent_child_sub_child_name"
from
	"parent" "Parent"
left join "child" "Parent__Parent_child" on
	"Parent__Parent_child"."parent_id" = Parent.parentId
where
	("Parent"."id" = $1)

Problematic part is Parent.parentId in
"Parent__Parent_child"."parent_id" = Parent.parentId
Replacing it with "Parent"."id" returns valid result

Steps to reproduce

@Entity()
export class Parent {
  @PrimaryColumn()
  id: string;

  @OneToOne(() => Child, (item) => item.parent)
  child?: Child;
}

@Entity("child")
export class Child {
  @PrimaryGeneratedColumn("uuid")
  id?: string;

  @Column({ type: "varchar", name: "parent_id", nullable: false, unique: true })
  parentId: string;

  @Column({ type: "varchar", name: "sub_child_name", nullable: false })
  subChildName: string;

  @OneToOne(() => Parent, (item) => item.child, { onDelete: "CASCADE" })
  @JoinColumn({ name: "parent_id", referencedColumnName: "id" })
  parent?: Parent;

  @ManyToOne(() => SubChild, (item) => item.childs, { onDelete: "CASCADE" })
  @JoinColumn([
    { name: "parent_id", referencedColumnName: "parentId" },
    { name: "sub_child_name", referencedColumnName: "childName" },
  ])
  subChild?: SubChild;
}

@Entity("sub_child")
@Unique("UQ_ parent_childName", ["parentId", "childName"])
export class SubChild {
  @PrimaryGeneratedColumn("uuid")
  id?: string;

  @Column()
  parentId: string;

  @Column()
  childName: string;

  @ManyToOne(() => Parent)
  parent: Parent;

  @OneToMany(() => Child, (item) => item.subChild)
  childs?: Child[];
}

const parent = await this.parentRepo.find({
      where: {
        id: "AAA"
      },
      select: ["id"],
      relations: ["child"],
    });

This produces migration

public async up(queryRunner: QueryRunner): Promise<void> {
        await queryRunner.query(`CREATE TABLE "parent" ("id" character varying NOT NULL, CONSTRAINT "PK_bf93c41ee1ae1649869ebd05617" PRIMARY KEY ("id"))`);
        await queryRunner.query(`CREATE TABLE "sub_child" ("id" uuid NOT NULL DEFAULT uuid_generate_v4(), "parentId" character varying NOT NULL, "childName" character varying NOT NULL, CONSTRAINT "UQ_ parent_childName" UNIQUE ("parentId", "childName"), CONSTRAINT "PK_e4a8dfeabd861a2c907e0a89e8c" PRIMARY KEY ("id"))`);
        await queryRunner.query(`CREATE TABLE "child" ("id" uuid NOT NULL DEFAULT uuid_generate_v4(), "parent_id" character varying NOT NULL, "sub_child_name" character varying NOT NULL, CONSTRAINT "UQ_4157a24f3378c1e06ae3a942868" UNIQUE ("parent_id"), CONSTRAINT "REL_4157a24f3378c1e06ae3a94286" UNIQUE ("parent_id"), CONSTRAINT "PK_4609b9b323ca37c6bc435ec4b6b" PRIMARY KEY ("id"))`);
        await queryRunner.query(`ALTER TABLE "sub_child" ADD CONSTRAINT "FK_541d7c27a2543472b351cd56295" FOREIGN KEY ("parentId") REFERENCES "parent"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`);
        await queryRunner.query(`ALTER TABLE "child" ADD CONSTRAINT "FK_4157a24f3378c1e06ae3a942868" FOREIGN KEY ("parent_id") REFERENCES "parent"("id") ON DELETE CASCADE ON UPDATE NO ACTION`);
        await queryRunner.query(`ALTER TABLE "child" ADD CONSTRAINT "FK_f1190fc68522883602bede4e872" FOREIGN KEY ("parent_id", "sub_child_name") REFERENCES "sub_child"("parentId","childName") ON DELETE CASCADE ON UPDATE NO ACTION`);
    }

My Environment

Dependency Version
Operating System
Node.js version 18.16.0
Typescript version 5.4.2
TypeORM version 0.3.15

Additional Context

PostgreSQL 15.5

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.

@nikelborm
Copy link
Collaborator

nikelborm commented Dec 14, 2024

Hi, could you please send the versions of PostgreSQL you're using and your package.json with lock.json?
And also your data source, please

@zbposs
Copy link
Author

zbposs commented Dec 18, 2024

Hi, seems like third entity is required to reproduce this, I have updated original comment with SubChild entity and generated migrations. If this is still not enough I will provide requested files. I am using PostgreSQL 15.5

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants