NestJS Repository报错:未找到TaskRepository元数据
TypeORM 报错:No metadata for "TaskRepository" was found 解决方法
问题描述
调用接口时触发以下错误:
[Nest] 15824 - 23/08/2023, 12:03:53 ERROR [ExceptionsHandler] No metadata for "TaskRepository" was found. EntityMetadataNotFoundError: No metadata for "TaskRepository" was found. at DataSource.getMetadata (D:\SaifAli\NestJS Demo Projects\nestjs-task-management\src\data-source\DataSource.ts:444:30) at Repository.get metadata [as metadata] (D:\SaifAli\NestJS Demo Projects\nestjs-task-management\src\repository\Repository.ts:53:40) at Repository.findOne (D:\SaifAli\NestJS Demo Projects\nestjs-task-management\src\repository\Repository.ts:577:42) at TasksService.getTaskById (D:\SaifAli\NestJS Demo Projects\nestjs-task-management\src\tasks\tasks.service.ts:37:50) at TasksController.getTaskById (D:\SaifAli\NestJS Demo Projects\nestjs-task-management\src\tasks\tasks.controller.ts:24:30)
依赖版本
"@nestjs/common": "^9.0.0", "@nestjs/core": "^9.0.0", "@nestjs/typeorm": "^10.0.0", "typeorm": "^0.3.17"
相关代码片段
typeorm.config.ts
import { TypeOrmModuleOptions } from "@nestjs/typeorm"; export const typeOrmConfig: TypeOrmModuleOptions = { type: 'postgres', host: 'localhost', port: 5432, username: 'postgres', password: 'root', database: 'taskmanagement', entities: [__dirname + '/../**/*.entity.{js,ts}'], synchronize: true, };
tasks.module.ts(原代码)
import { TypeOrmModule } from '@nestjs/typeorm'; import { Module } from '@nestjs/common'; import { TasksController } from './tasks.controller'; import { TasksService } from './tasks.service'; import { TaskRepository } from './task.repository'; @Module({ imports: [TypeOrmModule.forFeature([TaskRepository])], controllers: [TasksController], providers: [TasksService], }) export class TasksModule {}
task.entity.ts
import { TaskStatus } from "./task-status.enum"; import { Entity, PrimaryGeneratedColumn, Column } from 'typeorm'; @Entity() export class Task { @PrimaryGeneratedColumn() id: number; @Column() title: string; @Column() description: string; @Column() status: TaskStatus; }
task.repository.ts(原代码)
import { Repository } from 'typeorm'; import { Task } from './task.entity'; export class TaskRepository extends Repository<Task> { // 自定义仓库方法可写在此处 }
tasks.service.ts(原代码)
import { TaskRepository } from './task.repository'; import { Injectable, NotFoundException } from '@nestjs/common'; import { InjectRepository } from '@nestjs/typeorm'; import { Task } from './task.entity'; @Injectable() export class TasksService { constructor( @InjectRepository(TaskRepository) private taskRepository: TaskRepository, ) {}; async getTaskById(id: number): Promise<Task> { const record = await this.taskRepository.findOne({ where: { id } }); if (!record) { throw new NotFoundException(); } return record; } }
已尝试操作
- 切换旧版本TypeORM,引发新错误,故希望保留最新版本解决问题
- 将TypeORM配置中的
autoLoadEntities: true改为entities: [__dirname + '/../**/*.entity.{js,ts}'],无效果
解决方案
TypeORM 0.3+ 已弃用@EntityRepository装饰器,且不再支持直接将自定义仓库类传入TypeOrmModule.forFeature(),需按以下方式修改:
1. 修改自定义仓库类(task.repository.ts)
添加构造函数,通过DataSource初始化:
import { Repository, DataSource } from 'typeorm'; import { Task } from './task.entity'; export class TaskRepository extends Repository<Task> { constructor(dataSource: DataSource) { super(Task, dataSource.createEntityManager()); } // 自定义方法可保留在此处 }
2. 修改模块注册方式(tasks.module.ts)
将自定义仓库作为Provider注册,通过DataSource.getRepository().extend()创建实例:
import { TypeOrmModule } from '@nestjs/typeorm'; import { Module } from '@nestjs/common'; import { TasksController } from './tasks.controller'; import { TasksService } from './tasks.service'; import { Task } from './task.entity'; import { TaskRepository } from './task.repository'; import { DataSource } from 'typeorm'; @Module({ imports: [TypeOrmModule.forFeature([Task])], // 此处传入实体类Task,而非仓库 controllers: [TasksController], providers: [ TasksService, { provide: TaskRepository, useFactory: (dataSource: DataSource) => { return dataSource.getRepository(Task).extend(TaskRepository); }, inject: [DataSource], }, ], }) export class TasksModule {}
3. 保持Service注入方式不变
原tasks.service.ts的注入代码无需修改,依然可以通过@InjectRepository(TaskRepository)注入自定义仓库。
关键原因
TypeORM 0.3+ 重构了仓库系统,自定义仓库不再自动关联实体元数据,必须通过DataSource获取基础仓库后扩展,或手动传入实体和管理器初始化。
内容的提问来源于stack exchange,提问作者SAIF ALI
相关产品推荐
相关产品推荐

