본문 바로가기
Nest.js

[TypeORM] EntityRepository deprecated

by greeng00se 2022. 6. 22.

EntityRepository is deprecated

  • TypeORM 0.3.0 부터 EntityRepository가 deprecated 되었다.
  • nest에서 기존의 EntityRepository 을 사용하는 것과 사용방법이 유사한 해결방법을 찾게 되었다.
  • 직접 데코레이터를 생성하고, 데코레이터가 적용된 Repository를 받아줄 모듈을 사용하는 방법으로 해결 방법은 다음과 같다.

@CustomRepository decorator 생성

// db/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);
}
  • @CustomRepository 데코레이터를 생성해준다.
  • SetMetadata() 메서드를 이용하여 전달받은 Entity를 TYPEORM_EX_CUSTOM_REPOSITORY 메타데이터에 지정해준다.

TypeOrmExModule 생성

// db/typeorm-ex.module
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,
    };
  }
}
  • @CustomRepository 데코레이터가 적용된 Repository를 받아줄 모듈이다.
  • Reflect.getMetadata() 메서드로 메타데이터 키값인 TYPEORM_EX_CUSTOM_REPOSITORY에 해당되는 엔티티를 가져온다.
  • 메타데이터 키값에 해당하는 엔티티가 존재하는 경우 Factory를 이용하여 provider를 동적으로 생성하여 providers에 추가한다.

데코레이터 적용

@CustomRepository(Book)
export class BookRepository extends Repository<Book> {
  ...
}
  • @CustomRepository 데코레이터를 기존에 사용하던 @EntityRepository 데코레이터 적용하는 부분에 대체하여 사용한다.

모듈 설정

@Module({
  imports: [
    TypeOrmExModule.forCustomRepository([BookRepository]),
  ],
  ...
})
  • 전에 생성한 모듈을 추가 해준다.

Service에서의 사용

@Injectable()
export class BookService {
  constructor(
      private bookRepository: BookRepository,
  ) {}

  ...
}
  • 기존에 @EntityRepository를 사용한 경우 @InjectRepository 데코레이터를 사용했지만 해당 부분을 유지하면 오류가 발생한다.
  • 따라서 @CustomRepository를 생성하여 사용하는 경우 @InjectRepository를 제거하고 사용하자

참고 자료

'Nest.js' 카테고리의 다른 글

[TypeORM] Azure MySQL DB와 암호화 통신하기  (0) 2022.07.17