NestJS复用CRUD API时Repository显示undefined的问题
NestJS + TypeORM 自定义CRUD仓库报错
Cannot read properties of undefined (reading 'save') 解决方法 问题背景
使用NestJS、TypeORM和MySQL开发通用可复用CRUD API时,项目启动正常且数据库表已创建,但通过Postman提交测试数据触发内部服务器错误,日志显示repository为undefined,报错信息为Cannot read properties of undefined (reading 'save')。尝试用@InjectRepository(Repository)注入时,又出现"User does not have meta-data"错误。
核心问题分析
问题源于自定义仓库的依赖注入配置错误,Nest无法正确实例化并注入TypeORM的Repository实例,导致this.repository为undefined。
具体修复步骤
1. 给自定义仓库添加@Injectable()装饰器
Nest需要通过@Injectable()标记类为可注入的提供者,否则无法自动管理其依赖关系。修改BaseRepository和UserRepository:
Base Repository
import { DeepPartial, FindOneOptions, Repository } from 'typeorm'; import { BaseEntity } from '../base.entity/base.entity'; import { Injectable } from '@nestjs/common'; import { QueryDeepPartialEntity } from 'typeorm/query-builder/QueryPartialEntity'; // 添加@Injectable()装饰器 @Injectable() export abstract class BaseRepository<T extends BaseEntity> { constructor(private readonly repository: Repository<T>) {} async findAll(): Promise<T[]> { return this.repository.find(); } async findById(id: number): Promise<T> { const entity = await this.repository.findOne(id as FindOneOptions<T>); return entity; } async create(data: Partial<T>): Promise<T> { console.log('Received data for creation:', data); console.log('Received Repository:', this.repository); return await this.repository.save(data as DeepPartial<T>); } async update(id: number, data: Partial<T>): Promise<T> { await this.repository.update(id, data as QueryDeepPartialEntity<T>); return this.findById(id); } async delete(id: number): Promise<void> { await this.repository.delete(id); } }
UserRepository
import { Repository } from 'typeorm'; import { BaseRepository } from '../basic-crud/basic-repository'; import { User } from '../user.entity/user.entity'; import { Injectable } from '@nestjs/common'; import { InjectRepository } from '@nestjs/typeorm'; // 添加@Injectable()装饰器,并通过@InjectRepository注入实体仓库 @Injectable() export class UserRepository extends BaseRepository<User> { constructor(@InjectRepository(User) repository: Repository<User>) { super(repository); } }
2. 修正UserModule的TypeOrmModule配置
TypeOrmModule.forFeature()仅用于注册实体类,自定义仓库不需要在这里注册,移除UserRepository:
import { Module } from '@nestjs/common'; import { UserService } from 'src/services/user/user.service'; import { TypeOrmModule } from '@nestjs/typeorm'; import { UserRepository } from 'src/entities/user-repository/user-repository'; import { User } from 'src/entities/user.entity/user.entity'; import { UserController } from 'src/users/contollers/users/users.controller'; @Module({ // 仅注册User实体 imports: [TypeOrmModule.forFeature([User])], providers: [UserService, UserRepository], controllers: [UserController], exports: [UserService, UserRepository], }) export class UserModule {}
3. 验证UserService的注入逻辑
确保UserService中正确注入UserRepository:
// 示例UserService代码 import { Injectable } from '@nestjs/common'; import { UserRepository } from 'src/entities/user-repository/user-repository'; import { User } from 'src/entities/user.entity/user.entity'; @Injectable() export class UserService { constructor(private readonly userRepository: UserRepository) {} async createUser(userData: Partial<User>) { return this.userRepository.create(userData); } // 其他业务方法... }
"User does not have meta-data"错误说明
之前使用@InjectRepository(Repository)注入时出错,是因为@InjectRepository()需要传入具体的实体类(如User),而非泛型的Repository类型。TypeORM依赖实体类的元数据来生成对应的仓库实例。
内容的提问来源于stack exchange,提问作者themadhatter
相关产品推荐
相关产品推荐

