Nestjs with MikroOrm can't inject Entity Manager

38 Views Asked by At

I'm using an nx monorepo with nestjs and mikroOrm.

I've create a module called PersistanceModule that is defined like this:

import { Module } from '@nestjs/common';
import { MikroOrmModule } from '@mikro-orm/nestjs';
import { UserRepository } from './repositories/user-repository';
import { userSchema } from './configurations/user.configuration';

@Module({
  imports: [
    MikroOrmModule.forRoot({
      port: 5432,
      user: 'user',
      host: 'localhost',
      dbName: 'vector',
      password: 'password',
      entities: [userSchema],
      discovery: { warnWhenNoEntities: true },
    }),
  ],
  providers: [UserRepository],
  exports: [UserRepository],
})
export class PersistanceModule {}

And a repo that is defined like this:

import { EntityManager, EntityRepository } from '@mikro-orm/postgresql';
import { Injectable } from '@nestjs/common';
import { IUserRepository, User } from '@vector/domain';
import { userSchema } from '../configurations/user.configuration';
import { MikroORM } from '@mikro-orm/core';

Injectable();
export class UserRepository implements IUserRepository {
  private readonly _repository: EntityRepository<User>;

  constructor(
    private readonly orm: MikroORM,
    private readonly em: EntityManager
  ) {
    this._repository = em.getRepository(userSchema);
  }

  async findById(id: string): Promise<User | null> {
    const user = await this._repository.findOne({ id });
    return user;
  }
  async findByEmail(email: string): Promise<User | null> {
    const user = await this._repository.findOne({ email });
    return user;
  }
  async add(user: User): Promise<void> {
    let newUser = this._repository.create(user);
    await this._repository.getEntityManager().flush();
  }

  async update(user: User): Promise<void> {
    // await this.em.nativeUpdate(User, { id: user.id }, user);
  }

  async delete(id: string): Promise<void> {
    // await this.em.nativeDelete(User, { id });
  }
}

And I've defined my entities via schema to avoid polluting the domain with decorators.

import { BaseEntity } from '@vector/domain';
import { User } from '@vector/domain';
import { EntitySchema } from '@mikro-orm/core';
import { baseSchema } from './base.configuration';

export const userSchema = new EntitySchema<User, BaseEntity>({
  class: User,
  extends: baseSchema,
  schema: 'vector',
  properties: {
    externalId: { type: 'string', unique: true },
    email: { type: 'string', unique: true },
    password: { type: 'string' },
    active: { type: 'boolean', default: true },
    verificationToken: { type: 'string' },
  },
});

But when I start the app that is bundled with webpack, I'm getting always this error:

TypeError: Cannot read properties of undefined (reading 'getRepository') at new UserRepository (C:\Work\Vector\vector\dist\vector-client-api\development\webpack:\packages\infrastructure\persistance\src\lib\repositories\user-repository.ts:15:27) at Injector.instantiateClass (C:\Work\Vector\vector\node_modules@nestjs\core\injector\injector.js:365:19) at callback (C:\Work\Vector\vector\node_modules@nestjs\core\injector\injector.js:65:45) at Injector.resolveConstructorParams (C:\Work\Vector\vector\node_modules@nestjs\core\injector\injector.js:144:24) at Injector.loadInstance (C:\Work\Vector\vector\node_modules@nestjs\core\injector\injector.js:70:13) at Injector.loadProvider (C:\Work\Vector\vector\node_modules@nestjs\core\injector\injector.js:97:9) at C:\Work\Vector\vector\node_modules@nestjs\core\injector\instance-loader.js:56:13 at async Promise.all (index 4) at InstanceLoader.createInstancesOfProviders (C:\Work\Vector\vector\node_modules@nestjs\core\injector\instance-loader.js:55:9) at C:\Work\Vector\vector\node_modules@nestjs\core\injector\instance-loader.js:40:13

Does anyone now what this is and how to surpass it?

1

There are 1 best solutions below

0
Jay McDoniel On BEST ANSWER

The Injectable() method should be changed to the @Injectbale() decorator, so that Typescript properly emits the class's metadata so Nest is able to read it