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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 11:21:23