Search code examples
nestjstypeorm

How to workraound this TypeORM error, "EntityRepository is deprecated , use Repository.extend function instead"?


However, I can't find any Repository.extend method in Repository class and there's nothing about it in the documentation. How to solve this?

typeorm version: "^0.3.0"

I'm using nest js and trying to create a custom repository.


Solution

  • First of all:

    npm install @nestjs/typeorm@next
    

    NOTE

    In my project @nestjs/typeorm version is 9.0.0-next.2 and typeorm version is 0.3.6

    Create a folder named database in the src of your project then create two files in (typeorm-ex.decorator.ts and typeorm-ex.module.ts)

    // typeorm-ex.decorator.ts
    
    import { SetMetadata } from "@nestjs/common";
    
    export const TYPEORM_EX_CUSTOM_REPOSITORY = "TYPEORM_EX_CUSTOM_REPOSITORY";
    
    export function CustomRepository(entity: Function): ClassDecorator {
      return SetMetadata(TYPEORM_EX_CUSTOM_REPOSITORY, entity);
    }
    

    And next file

    // typeorm-ex.module.ts
    
    import { DynamicModule, Provider } from "@nestjs/common";
    import { getDataSourceToken } from "@nestjs/typeorm";
    import { DataSource } from "typeorm";
    import { TYPEORM_EX_CUSTOM_REPOSITORY } from "./typeorm-ex.decorator";
    
    export class TypeOrmExModule {
      public static forCustomRepository<T extends new (...args: any[]) => any>(repositories: T[]): DynamicModule {
        const providers: Provider[] = [];
    
        for (const repository of repositories) {
          const entity = Reflect.getMetadata(TYPEORM_EX_CUSTOM_REPOSITORY, repository);
    
          if (!entity) {
            continue;
          }
    
          providers.push({
            inject: [getDataSourceToken()],
            provide: repository,
            useFactory: (dataSource: DataSource): typeof repository => {
              const baseRepository = dataSource.getRepository<any>(entity);
              return new repository(baseRepository.target, baseRepository.manager, baseRepository.queryRunner);
            },
          });
        }
    
        return {
          exports: providers,
          module: TypeOrmExModule,
          providers,
        };
      }
    }
    

    Open your AppModule and modify it like the following:

    @Module({
      imports: [
        TypeOrmModule.forRoot({
          type: 'mssql',
          ...
          entities: [Photo],
        }),
        TypeOrmExModule.forCustomRepository([PhotoRepository]),
        ...
      ],
      controllers: [AppController],
      providers: [
        AppService
      ],
    })
    export class AppModule { }
    

    You can create your customer repository like the following :

    @CustomRepository(Photo)
    export class PhotoRepository extends Repository<Photo> {
        public async getAllPhoto() {
            const query = this.createQueryBuilder('photo')
                .where('photo.isPublished = :isPublished', { isPublished: true })
            const photos = await query.getMany()
            return photos
        }
    }
    

    Everything works perfectly.

    Thanks to @anchan828