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

NestJS使用TypeORM 0.3.x时findOneBy未定义错误求助

解决NestJS + TypeORM 0.3.x中findOneBy undefined及EntityRepository废弃问题

问题根源

TypeORM 0.3.x版本正式废弃了EntityRepository装饰器,你原来通过@EntityRepository(Task)继承Repository<Task>的方式已不再生效,导致TasksRepository无法被NestJS正确实例化,注入到TasksService中的taskRepository实际为undefined,因此调用findOneBy时触发类型错误。

解决方案

下面提供两种适配TypeORM 0.3+的方案,按需选择:

方案一:重构自定义TasksRepository(保留封装逻辑)

如果需要保留自定义的Repository封装,按以下步骤修改:

  1. 更新tasks.repository.ts
    移除@EntityRepository装饰器,通过DataSource手动初始化Repository:
import { Injectable } from '@nestjs/common';
import { DataSource, Repository } from 'typeorm';
import { Task } from './task.entity';
import { CreateTaskDto } from './dto/create-task.dto';
import { TaskStatus } from './task-status.enum';

@Injectable()
export class TasksRepository extends Repository<Task> {
  constructor(private dataSource: DataSource) {
    super(Task, dataSource.manager);
  }

  // 示例自定义方法:创建任务
  async createTask(createTaskDto: CreateTaskDto): Promise<Task> {
    const { title, description } = createTaskDto;
    const task = this.create({
      title,
      description,
      status: TaskStatus.OPEN,
    });
    await this.save(task);
    return task;
  }
}
  1. 更新tasks.service.ts
    直接注入自定义的TasksRepository(无需@InjectRepository装饰器):
import { Injectable, NotFoundException } from '@nestjs/common';
import { TasksRepository } from './tasks.repository';
import { Task } from './task.entity';
import { CreateTaskDto } from './dto/create-task.dto';

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

  async getTaskById(id: string): Promise<Task> {
    const found = await this.tasksRepository.findOneBy({ id });
    if (!found) {
      throw new NotFoundException(`Task with ID "${id}" not found`);
    }
    return found;
  }

  async createTask(createTaskDto: CreateTaskDto): Promise<Task> {
    return this.tasksRepository.createTask(createTaskDto);
  }
}

方案二:移除自定义Repository,直接使用原生TypeORM Repository

如果不需要自定义Repository的封装逻辑,直接使用原生Repository更简洁:

  1. 删除tasks.repository.ts

  2. 更新tasks.service.ts
    用@InjectRepository(Task)注入原生Repository:

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

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

  async getTaskById(id: string): Promise<Task> {
    const found = await this.tasksRepository.findOneBy({ id });
    if (!found) {
      throw new NotFoundException(`Task with ID "${id}" not found`);
    }
    return found;
  }

  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;
  }
}

额外注意事项

  • 确保实体Task中的id字段类型与请求传入的id类型一致(比如实体定义为string,则无需转换;若为number,需将id转为数字后传入findOneBy)。
  • 无需降级TypeORM到0.2.x,以上方案完全适配0.3.11版本。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 09:00:38