You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 22:18:11