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

NestJS+TypeORM+PostgreSQL报错:找不到TasksRepository元数据

PostgreSQL数据库操作报错:No metadata for "TasksRepository" was found

问题描述

尝试为实体创建仓库用于PostgreSQL数据库操作时,持续抛出以下错误:

[Nest] 32358 ERROR [ExceptionsHandler] No metadata for "TasksRepository" was found.

测试控制器接口时返回500内部服务器错误,相关代码如下:

相关代码

tasks.module.ts

import { Module } from '@nestjs/common';
import { TasksController } from './tasks.controller';
import { TasksService } from './tasks.service';
import { TypeOrmModule } from '@nestjs/typeorm';
import { TasksRepository } from './tasks.repository';

@Module({
  imports: [TypeOrmModule.forFeature([TasksRepository])],
  controllers: [TasksController],
  providers: [TasksService]
})
export class TasksModule {}

tasks.repository.ts

import { EntityRepository, Repository } from "typeorm";
import { Task } from "./tasks.entity";

@EntityRepository(Task)
export class TasksRepository extends Repository<Task> {
    
}

tasks.service.ts

import { Injectable, NotFoundException } from '@nestjs/common';
import { TaskStatus } from './tasks.enum';
import { CreateTaskDto } from 'src/dto/tasks/create-task.dto';
import { TasksRepository } from './tasks.repository';
import { InjectRepository } from '@nestjs/typeorm';
import { Task } from './tasks.entity';

@Injectable()
export class TasksService {
    constructor(
        @InjectRepository(TasksRepository)
        private tasksRepository: TasksRepository,
    ) {}

    async getTaskById(id: string): Promise<Task> {
        const task = await this.tasksRepository.findOne({where: {id}});
        if (!task) {
            throw new NotFoundException;
        }
        return task;
    }

    async createTask(createTaskDto: CreateTaskDto): Promise<Task> {
        const { title, description } = createTaskDto;
        const task = this.tasksRepository.create({
            title,
            description,
            status: TaskStatus.OPEN,
        });

        await this.tasksRepository.save(task);
        return task;
    }
}

tasks.controller.ts

import { Controller, Get, Param, Post, Body } from '@nestjs/common';
import { TasksService } from './tasks.service';
import { Task } from './tasks.entity';
import { CreateTaskDto } from 'src/dto/tasks/create-task.dto';

@Controller('tasks')
export class TasksController {
    constructor(private tasksService: TasksService) {}

    @Get('/:id')
    getTaskById(@Param('id') id: string): Promise<Task> { 
        return this.tasksService.getTaskById(id);
    }

    @Post()
    createTask(@Body() createTaskDto: CreateTaskDto): Promise<Task> {
        return this.tasksService.createTask(createTaskDto);
    }
}

app.module.ts

import { Module } from '@nestjs/common';
import { TasksModule } from './modules/tasks/tasks.module';
import { TypeOrmModule } from '@nestjs/typeorm';

@Module({
  imports: [
    TasksModule,
    TypeOrmModule.forRoot({
      type: 'postgres',
      host: 'localhost',
      port: 5432,
      username: 'postgres',
      password: 'postgres',
      database: 'task-management',
      autoLoadEntities: true,
      synchronize: true,
    }),
  ],
})
export class AppModule {}

解决办法

核心原因

TypeORM的@EntityRepository装饰器已被废弃,NestJS与TypeORM的集成逻辑不再支持通过该方式注册自定义仓库,导致元数据无法被识别。

方案一:适配新版本的自定义仓库

  1. 修改tasks.repository.ts
    移除@EntityRepository,改用@Injectable并通过DataSource初始化仓库:
import { Injectable, Repository, DataSource } from "@nestjs/typeorm";
import { Task } from "./tasks.entity";

@Injectable()
export class TasksRepository extends Repository<Task> {
  constructor(private dataSource: DataSource) {
    super(Task, dataSource.createEntityManager());
  }
}
  1. 更新tasks.module.ts
    注册Task实体而非仓库,并将TasksRepository加入providers:
import { Module } from '@nestjs/common';
import { TasksController } from './tasks.controller';
import { TasksService } from './tasks.service';
import { TypeOrmModule } from '@nestjs/typeorm';
import { TasksRepository } from './tasks.repository';
import { Task } from './tasks.entity';

@Module({
  imports: [TypeOrmModule.forFeature([Task])],
  controllers: [TasksController],
  providers: [TasksService, TasksRepository]
})
export class TasksModule {}
  1. tasks.service.ts无需修改
    原有的@InjectRepository(TasksRepository)注入方式依然有效。

方案二:直接使用实体仓库(无需自定义仓库)

如果不需要在仓库中添加自定义方法,可以简化实现:

  1. 删除tasks.repository.ts
  2. 修改tasks.service.ts
    直接注入Task实体对应的仓库:
import { Injectable, NotFoundException } from '@nestjs/common';
import { TaskStatus } from './tasks.enum';
import { CreateTaskDto } from 'src/dto/tasks/create-task.dto';
import { InjectRepository } from '@nestjs/typeorm';
import { Task } from './tasks.entity';
import { Repository } from 'typeorm';

@Injectable()
export class TasksService {
    constructor(
        @InjectRepository(Task)
        private tasksRepository: Repository<Task>,
    ) {}

    // 其余代码保持不变
}
  1. 更新tasks.module.ts
    仅注册Task实体:
import { Module } from '@nestjs/common';
import { TasksController } from './tasks.controller';
import { TasksService } from './tasks.service';
import { TypeOrmModule } from '@nestjs/typeorm';
import { Task } from './tasks.entity';

@Module({
  imports: [TypeOrmModule.forFeature([Task])],
  controllers: [TasksController],
  providers: [TasksService]
})
export class TasksModule {}

额外检查

确保Task实体正确使用@Entity()装饰器,示例如下:

import { Entity, Column, PrimaryGeneratedColumn } from 'typeorm';
import { TaskStatus } from './tasks.enum';

@Entity()
export class Task {
  @PrimaryGeneratedColumn('uuid')
  id: string;

  @Column()
  title: string;

  @Column()
  description: string;

  @Column({
    type: 'enum',
    enum: TaskStatus,
    default: TaskStatus.OPEN,
  })
  status: TaskStatus;
}

内容的提问来源于stack exchange,提问作者motionless570

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 02:16:09