From 4044caa5306ae99131932e5bf27276b941a24be5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Ad=C3=A1mek?= Date: Mon, 26 Jan 2026 18:16:16 +0100 Subject: [PATCH] fix: support custom repositories with `EntitySchema`/`defineEntity` When using `forFeature()` with entities defined via `EntitySchema` or `defineEntity`, custom repositories were not being registered as providers. This was because the metadata lookup only checked for class-based entities. Now the code properly handles `EntitySchema` instances by accessing their metadata directly via `entity.meta`. Closes mikro-orm/mikro-orm#6701 --- src/mikro-orm.providers.ts | 4 +-- tests/entities/baz.entity.ts | 47 ++++++++++++++++++++++++++++ tests/mikro-orm.module.test.ts | 57 ++++++++++++++++++++++++++++++---- 3 files changed, 100 insertions(+), 8 deletions(-) create mode 100644 tests/entities/baz.entity.ts diff --git a/src/mikro-orm.providers.ts b/src/mikro-orm.providers.ts index 0132bf6..0407ebd 100644 --- a/src/mikro-orm.providers.ts +++ b/src/mikro-orm.providers.ts @@ -1,4 +1,4 @@ -import { EntityManager, MetadataStorage, MikroORM, type AnyEntity, type ForkOptions } from '@mikro-orm/core'; +import { EntityManager, EntitySchema, MetadataStorage, MikroORM, type AnyEntity, type ForkOptions } from '@mikro-orm/core'; import { Scope, type InjectionToken, type Provider, type Type } from '@nestjs/common'; import { @@ -117,7 +117,7 @@ export function createMikroOrmRepositoryProviders(entities: EntityName { - const meta = metadata.find(meta => meta.class === entity); + const meta = entity instanceof EntitySchema ? entity.meta : metadata.find(meta => meta.class === entity); const repository = meta?.repository as unknown as (() => InjectionToken) | undefined; if (repository) { diff --git a/tests/entities/baz.entity.ts b/tests/entities/baz.entity.ts new file mode 100644 index 0000000..c85fd35 --- /dev/null +++ b/tests/entities/baz.entity.ts @@ -0,0 +1,47 @@ +import { EntityRepository, EntitySchema, defineEntity, p } from '@mikro-orm/core'; + +// EntitySchema test +export interface IBaz { + id: number; + name: string; +} + +export class BazRepository extends EntityRepository { + + customMethod(): string { + return 'custom'; + } + +} + +export const Baz = new EntitySchema({ + name: 'Baz', + repository: () => BazRepository, + properties: { + id: { type: 'number', primary: true }, + name: { type: 'string' }, + }, +}); + +// defineEntity test +export interface IQux { + id: number; + title: string; +} + +export class QuxRepository extends EntityRepository { + + anotherCustomMethod(): string { + return 'another-custom'; + } + +} + +export const Qux = defineEntity({ + name: 'Qux', + repository: () => QuxRepository, + properties: { + id: p.integer().primary(), + title: p.string(), + }, +}); diff --git a/tests/mikro-orm.module.test.ts b/tests/mikro-orm.module.test.ts index 030d532..0d484e2 100644 --- a/tests/mikro-orm.module.test.ts +++ b/tests/mikro-orm.module.test.ts @@ -15,6 +15,7 @@ import { } from '@mikro-orm/nestjs'; import { Bar } from './entities/bar.entity.js'; import { Foo } from './entities/foo.entity.js'; +import { Baz, BazRepository, Qux, QuxRepository } from './entities/baz.entity.js'; const testOptions = defineConfig({ dbName: ':memory:', @@ -91,7 +92,7 @@ describe('MikroORM Module', () => { imports: [MikroOrmModule.forRoot(testOptions)], }).compile(); - const orm = module.get(MikroORM); + const orm = module.get(MikroORM); expect(orm).toBeDefined(); expect(orm.config.get('contextName')).toBe('default'); expect(module.get(EntityManager)).toBeDefined(); @@ -109,7 +110,7 @@ describe('MikroORM Module', () => { ], }).compile(); - const orm = module.get(MikroORM); + const orm = module.get(MikroORM); expect(orm).toBeDefined(); expect(orm.config.get('contextName')).toBe('default'); expect(module.get(EntityManager)).toBeDefined(); @@ -127,7 +128,7 @@ describe('MikroORM Module', () => { ], }).compile(); - const orm = module.get(MikroORM); + const orm = module.get(MikroORM); expect(orm).toBeDefined(); expect(orm.config.get('contextName')).toBe('default'); expect(module.get(EntityManager)).toBeDefined(); @@ -149,7 +150,7 @@ describe('MikroORM Module', () => { ], }).compile(); - const orm = module.get(MikroORM); + const orm = module.get(MikroORM); expect(orm).toBeDefined(); expect(orm.config.get('contextName')).toBe('default'); expect(module.get(EntityManager)).toBeDefined(); @@ -261,7 +262,7 @@ describe('MikroORM Module', () => { imports: [...MikroOrmModule.forRoot([testOptions]), MikroOrmModule.forFeature([Foo])], }).compile(); - const orm = module.get(MikroORM); + const orm = module.get(MikroORM); const entityManager = module.get(EntityManager); const repository = module.get>(getRepositoryToken(Foo)); @@ -285,7 +286,7 @@ describe('MikroORM Module', () => { ], }).compile(); - const orm = module.get(MikroORM); + const orm = module.get(MikroORM); const entityManager = module.get(EntityManager); const repository = module.get>(getRepositoryToken(Foo)); @@ -295,6 +296,50 @@ describe('MikroORM Module', () => { await orm.close(); }); + + it('forFeature should return custom repository for EntitySchema (GH6701)', async () => { + const module = await Test.createTestingModule({ + imports: [ + MikroOrmModule.forRoot({ + ...testOptions, + entities: [Baz], + }), + MikroOrmModule.forFeature([Baz]), + ], + }).compile(); + + const orm = module.get(MikroORM); + const repository = module.get(BazRepository); + + expect(orm).toBeDefined(); + expect(repository).toBeDefined(); + expect(repository).toBeInstanceOf(BazRepository); + expect(repository.customMethod()).toBe('custom'); + + await orm.close(); + }); + + it('forFeature should return custom repository for defineEntity (GH6701)', async () => { + const module = await Test.createTestingModule({ + imports: [ + MikroOrmModule.forRoot({ + ...testOptions, + entities: [Qux], + }), + MikroOrmModule.forFeature([Qux]), + ], + }).compile(); + + const orm = module.get(MikroORM); + const repository = module.get(QuxRepository); + + expect(orm).toBeDefined(); + expect(repository).toBeDefined(); + expect(repository).toBeInstanceOf(QuxRepository); + expect(repository.anotherCustomMethod()).toBe('another-custom'); + + await orm.close(); + }); }); describe('Multiple Databases', () => {