Metadata for entity CustomBaseEntity not found
Describe the bug
- Given we are using Entity Schema definitions
- And we have a
CustomBaseEntityabstract class with its schema - And we have a
Userentity class with its schema - And both schemas were imported in the module using
MikroORMModule.forFeature([customBaseEntitySchema, userSchema]) - And we're using the
autoLoadEntitites: trueoption. - When we initialize a Nest module
- Then we got an error:
MetadataError: Metadata for entity CustomBaseEntity not found
Stack trace
stdout | src/mikro-orm/mikro-orm-internal.module.spec.ts > MikroOrmInternalModule > connects to the database
[info] MikroORM version: 5.7.14
[discovery] ORM entity discovery started, using ReflectMetadataProvider
[discovery] - processing entity CustomBaseEntity
[discovery] - processing entity User
[discovery] - entity discovery finished, found 2 entities, took 11 ms
stdout | src/mikro-orm/mikro-orm-internal.module.spec.ts > MikroOrmInternalModule > connects to the database
[info] MikroORM successfully connected to database postgres on postgresql://postgres:*****@localhost:5435
stdout | src/mikro-orm/mikro-orm-internal.module.spec.ts > MikroOrmInternalModule > connects to the database
[query] select 1 from pg_database where datname = 'postgres' [took 1 ms, 1 result]
✓ src/app.controller.spec.ts (1)
❯ src/mikro-orm/mikro-orm-internal.module.spec.ts (2) 53117ms
❯ MikroOrmInternalModule (2) 53116ms
× connects to the database 53114ms
⠴ [ beforeEach ]
⠸ [ afterEach ]
↓ creates a new user [skipped]
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ Failed Tests 1 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯
FAIL src/mikro-orm/mikro-orm-internal.module.spec.ts > MikroOrmInternalModule > connects to the database
MetadataError: Metadata for entity CustomBaseEntity not found
❯ Function.missingMetadata node_modules/@mikro-orm/core/errors.js:178:16
❯ MetadataStorage.get node_modules/@mikro-orm/core/metadata/MetadataStorage.js:54:42
❯ SqlEntityManager.getRepository node_modules/@mikro-orm/core/EntityManager.js:65:40
❯ SqlEntityManager.getRepository node_modules/@mikro-orm/knex/SqlEntityManager.js:41:22
❯ InstanceWrapper.useFactory [as metatype] node_modules/@mikro-orm/nestjs/mikro-orm.providers.js:98:34
❯ TestingInjector.instantiateClass node_modules/@nestjs/core/injector/injector.js:368:55
❯ callback node_modules/@nestjs/core/injector/injector.js:65:45
❯ TestingInjector.resolveConstructorParams node_modules/@nestjs/core/injector/injector.js:144:24
❯ TestingInjector.loadInstance node_modules/@nestjs/core/injector/injector.js:70:13
To Reproduce Steps to reproduce the behavior:
- Clone the minimum reproducible code repository: https://github.com/thiagomini/nest-mikro-orm-example/tree/bug/custom-base-entity
- run
yarn - run
docker compose up -d - run
yarn test
Expected behavior The module should have been initialized correctly.
Additional context I'm using Vitest for tests, for it also fails using Jest.
Versions
| Dependency | Version |
|---|---|
| node | 18.12.1 |
| typescript | 5.1.3 |
| mikro-orm | 5.7.14 |
| pg | 8.11.2 |
And both schemas were imported in the module using MikroORMModule.forFeature([customBaseEntitySchema, userSchema])
This is your problem, base entities don't exist on runtime, you cannot call forFeature on those. The forFeature call only registers the repositories to the nest DI container, and a base entity does not represent anything. They are inlined to the actual entities that extend them during discovery phase.
FYI in current version you don't have to discover base entities, they will be discovered automatically. In fact, any entity that is referred by a class reference is discovered automatically, e.g. if your Book entity has a m:1 relation to Author entity specified as @ManyToOne(() => Author), that Author entity is also discovered automatically.
So things should work just fine if you do MikroORMModule.forFeature([userSchema]) instead.
I guess we could ignore base entities in the forFeature call, as they won't break anything, it's just a no-op to have them there. But that would be probably a bit bigger refactor, as we would have to be able to tell whether something is a known base entity, which we currently can't do, once the ORM is initialized, those are simply not there at all.
Hey @B4nan , I appreciate the feedback, but even when I remove the baseEntitySchema from the registration process (see test here) it still gives me the same error:
MetadataError: Metadata for entity CustomBaseEntity not found
Could you help me further with that? Thanks!
Edit: I believe this has to do with two facts:
- I'm using schemas to register the entities
- I'm using the
autoLoadEntities: trueconfiguration
I think the problem is that using the autoLoadEntities requires us to register schemas using the forFeature() method. Still, as you said, apparently we shouldn't be registering the base entity schema like that. Is there any other solution?
Sure, I will take a closer look at the repro when I have a moment, let's reopen then.
https://github.com/mikro-orm/nestjs/pull/151#issuecomment-2119305771