diff --git a/packages/core/src/unit-of-work/ChangeSetPersister.ts b/packages/core/src/unit-of-work/ChangeSetPersister.ts index 35e71845cf5f..0092553dc8fc 100644 --- a/packages/core/src/unit-of-work/ChangeSetPersister.ts +++ b/packages/core/src/unit-of-work/ChangeSetPersister.ts @@ -71,7 +71,7 @@ export class ChangeSetPersister { const chunk = changeSets.slice(i, i + size); const pks = chunk.map(cs => cs.getPrimaryKey()); options = this.propagateSchemaFromMetadata(meta, options); - await this.driver.nativeDelete(meta.className, { [pk]: { $in: pks } } as FilterQuery, options); + await this.driver.nativeDelete(meta.root.className, { [pk]: { $in: pks } } as FilterQuery, options); } } diff --git a/tests/features/single-table-inheritance/GH5303.test.ts b/tests/features/single-table-inheritance/GH5303.test.ts new file mode 100644 index 000000000000..3892440c0e73 --- /dev/null +++ b/tests/features/single-table-inheritance/GH5303.test.ts @@ -0,0 +1,115 @@ +import { Cascade, Collection, Entity, ManyToOne, MikroORM, OneToMany, PrimaryKey, Property } from '@mikro-orm/sqlite'; + +@Entity() +class User { + + @PrimaryKey() + id!: number; + + @OneToMany({ + entity: () => CoverPicture, + mappedBy: 'cover_user', + orphanRemoval: true, + eager: true, + cascade: [Cascade.ALL], + }) + cover_pictures: Collection = new Collection(this); + + @OneToMany({ + entity: () => ProfilePicture, + mappedBy: 'profile_user', + orphanRemoval: true, + eager: true, + cascade: [Cascade.ALL], + }) + profile_pictures: Collection = new Collection(this); + +} + +@Entity({ abstract: true, discriminatorColumn: 'type' }) +abstract class BasePicture { + + @PrimaryKey() + id!: number; + + @Property({ type: 'string', nullable: false }) + path: string; + + constructor(path: string) { + this.path = path; + } + +} + +@Entity({ discriminatorValue: 'cover' }) +class CoverPicture extends BasePicture { + + @ManyToOne({ entity: () => User }) + cover_user: User; + + constructor(path: string, user: User) { + super(path); + this.cover_user = user; + } + +} + +@Entity({ discriminatorValue: 'profile' }) +class ProfilePicture extends BasePicture { + + @ManyToOne({ entity: () => User }) + profile_user: User; + + constructor(path: string, user: User) { + super(path); + this.profile_user = user; + } + +} + +let orm: MikroORM; + +beforeAll(async () => { + orm = await MikroORM.init({ + dbName: ':memory:', + entities: [User, BasePicture, CoverPicture, ProfilePicture], + }); + await orm.schema.refreshDatabase(); +}); + +afterAll(async () => { + await orm.close(true); +}); + +test('user should be able to create/update pictures', async () => { + let user = new User(); + orm.em.create(User, user); + await orm.em.persist(user).flush(); + orm.em.clear(); + + user = await orm.em.findOneOrFail(User, { id: user.id }); + user.cover_pictures.add(new CoverPicture('/path/1', user)); + user.profile_pictures.add(new ProfilePicture('/path/2', user)); + await orm.em.persist(user).flush(); + orm.em.clear(); + + user = await orm.em.findOneOrFail(User, { id: user.id }); + expect(user.cover_pictures.length).toBe(1); + expect(user.profile_pictures.length).toBe(1); + + // update pictures + user.cover_pictures.removeAll(); + user.profile_pictures.removeAll(); + + user.cover_pictures.add(new CoverPicture('/path/3', user)); + user.profile_pictures.add(new ProfilePicture('/path/4', user)); + + await orm.em.persist(user).flush(); + orm.em.clear(); + + user = await orm.em.findOneOrFail(User, { id: user.id }); + expect(user.cover_pictures.length).toBe(1); + expect(user.profile_pictures.length).toBe(1); + expect(user.cover_pictures[0].path).toBe('/path/3'); + expect(user.profile_pictures[0].path).toBe('/path/4'); +});