diff --git a/src/metadata-builder/EntityMetadataValidator.ts b/src/metadata-builder/EntityMetadataValidator.ts index d1d376662f..e62ae2c803 100644 --- a/src/metadata-builder/EntityMetadataValidator.ts +++ b/src/metadata-builder/EntityMetadataValidator.ts @@ -69,6 +69,7 @@ export class EntityMetadataValidator { const sameDiscriminatorValueEntityMetadata = allEntityMetadatas.find(metadata => { return metadata !== entityMetadata && (metadata.inheritancePattern === "STI" || metadata.tableType === "entity-child") + && metadata.tableName === entityMetadata.tableName && metadata.discriminatorValue === entityMetadata.discriminatorValue && metadata.inheritanceTree.some(parent => entityMetadata.inheritanceTree.indexOf(parent) !== -1); }); diff --git a/test/github-issues/8522/entity/BaseEntity.ts b/test/github-issues/8522/entity/BaseEntity.ts new file mode 100644 index 0000000000..787a2ccb0d --- /dev/null +++ b/test/github-issues/8522/entity/BaseEntity.ts @@ -0,0 +1,13 @@ +import { PrimaryGeneratedColumn, CreateDateColumn, UpdateDateColumn } from "../../../../src"; + +export class BaseEntity { + @PrimaryGeneratedColumn() + id: number; + + @CreateDateColumn() + createdAt: Date; + + @UpdateDateColumn() + updatedAt: Date; + + } \ No newline at end of file diff --git a/test/github-issues/8522/entity/ClientRole.ts b/test/github-issues/8522/entity/ClientRole.ts new file mode 100644 index 0000000000..fd6f61cc18 --- /dev/null +++ b/test/github-issues/8522/entity/ClientRole.ts @@ -0,0 +1,6 @@ +import { ChildEntity } from "../../../../src"; +import { Role } from "./Role"; + +@ChildEntity('internal') +export class ClientRole extends Role { +} \ No newline at end of file diff --git a/test/github-issues/8522/entity/InternalRole.ts b/test/github-issues/8522/entity/InternalRole.ts new file mode 100644 index 0000000000..e536fb5652 --- /dev/null +++ b/test/github-issues/8522/entity/InternalRole.ts @@ -0,0 +1,6 @@ +import { ChildEntity } from "../../../../src"; +import { Role } from "./Role"; + +@ChildEntity('internal') +export class InternalRole extends Role { +} \ No newline at end of file diff --git a/test/github-issues/8522/entity/InternalUser.ts b/test/github-issues/8522/entity/InternalUser.ts new file mode 100644 index 0000000000..f11ac87d1f --- /dev/null +++ b/test/github-issues/8522/entity/InternalUser.ts @@ -0,0 +1,6 @@ +import { ChildEntity } from "../../../../src"; +import { User } from "./User"; + +@ChildEntity('internal') +export class InternalUser extends User { +} \ No newline at end of file diff --git a/test/github-issues/8522/entity/Role.ts b/test/github-issues/8522/entity/Role.ts new file mode 100644 index 0000000000..1343507d28 --- /dev/null +++ b/test/github-issues/8522/entity/Role.ts @@ -0,0 +1,14 @@ +import { TableInheritance, Column, Entity } from "../../../../src"; + +import { BaseEntity } from "./BaseEntity"; + +@Entity() +@TableInheritance({ column: { type: 'varchar', name: 'type' } }) +export class Role extends BaseEntity { + @Column() + name: string; + + @Column() + description: string; + +} \ No newline at end of file diff --git a/test/github-issues/8522/entity/User.ts b/test/github-issues/8522/entity/User.ts new file mode 100644 index 0000000000..c2553224cd --- /dev/null +++ b/test/github-issues/8522/entity/User.ts @@ -0,0 +1,13 @@ +import { TableInheritance, Column, Entity } from "../../../../src"; +import { BaseEntity } from "./BaseEntity"; + +@Entity() +@TableInheritance({ column: { type: 'varchar', name: 'type' } }) +export abstract class User extends BaseEntity { + @Column() + firstName: string; + + @Column() + lastName: string; + +} \ No newline at end of file diff --git a/test/github-issues/8522/issue-8522.ts b/test/github-issues/8522/issue-8522.ts new file mode 100644 index 0000000000..47869d3c32 --- /dev/null +++ b/test/github-issues/8522/issue-8522.ts @@ -0,0 +1,90 @@ +import "reflect-metadata"; +import { createTestingConnections, closeTestingConnections, reloadTestingDatabases } from "../../utils/test-utils"; +import { Connection } from "../../../src/connection/Connection"; +import { expect } from "chai"; +import { InternalUser } from "./entity/InternalUser"; +import { InternalRole } from "./entity/InternalRole"; +import { User } from "./entity/User"; +import { Role } from "./entity/Role"; +import { BaseEntity, TypeORMError } from "../../../src"; +import { ClientRole } from "./entity/ClientRole"; +import { afterEach } from "mocha"; + +describe("github issues > #8522 Single table inheritance returns the same discriminator value error for unrelated tables where their parents extend from the same entity", () => { + let connections: Connection[]; + + after(() => closeTestingConnections(connections)); + afterEach(() => closeTestingConnections(connections)); + + describe("Unrelated tables",()=>{ + before( + async () => + (connections = await createTestingConnections({ + entities: [BaseEntity, InternalUser, InternalRole, Role, User], + schemaCreate: true, + dropSchema: true, + })) + ); + beforeEach(() => reloadTestingDatabases(connections)); + + it("should loads internal user and internal role", () => Promise.all(connections.map(async connection => { + const id = 1; + const date = new Date(); + + const firstName = "Jane"; + const lastName = "Walker"; + + const name = "admin"; + const description = "All permissions"; + + const internalUser = new InternalUser(); + internalUser.id = id; + internalUser.firstName = firstName; + internalUser.lastName = lastName; + internalUser.createdAt = date; + internalUser.updatedAt = date; + + await connection.manager.save(internalUser); + + const internalRole = new InternalRole(); + internalRole.id = id; + internalRole.name = name; + internalRole.description = description; + internalRole.createdAt = date; + internalRole.updatedAt = date; + + await connection.manager.save(internalRole); + + let users = await connection.manager + .createQueryBuilder(User, "user") + .getMany(); + + expect(users[0].id).to.be.equal(id); + expect(users[0].firstName).to.be.equal(firstName); + expect(users[0].lastName).to.be.equal(lastName); + expect(users[0].createdAt.should.be.instanceOf(Date)); + expect(users[0].updatedAt.should.be.instanceOf(Date)); + + let roles = await connection.manager + .createQueryBuilder(Role, "role") + .getMany(); + + expect(roles[0].id).to.be.equal(id); + expect(roles[0].name).to.be.equal(name); + expect(roles[0].description).to.be.equal(description); + expect(roles[0].createdAt.should.be.instanceOf(Date)); + expect(roles[0].updatedAt.should.be.instanceOf(Date)); + }))); + }); + + describe("Related tables", () => { + + it("Should throw error when related tables have the same discriminator", async () =>{ + await createTestingConnections({ + entities: [BaseEntity, ClientRole, InternalRole, Role, User], + schemaCreate: true, + dropSchema: true, + }).should.be.rejectedWith(TypeORMError,`Entities ClientRole and InternalRole have the same discriminator values. Make sure they are different while using the @ChildEntity decorator.`); + }); + }); +}); \ No newline at end of file