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的集成逻辑不再支持通过该方式注册自定义仓库,导致元数据无法被识别。
方案一:适配新版本的自定义仓库
- 修改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()); } }
- 更新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 {}
- tasks.service.ts无需修改
原有的@InjectRepository(TasksRepository)注入方式依然有效。
方案二:直接使用实体仓库(无需自定义仓库)
如果不需要在仓库中添加自定义方法,可以简化实现:
- 删除tasks.repository.ts
- 修改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>, ) {} // 其余代码保持不变 }
- 更新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
相关产品推荐
相关产品推荐

