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

NestJS+TypeORM执行种子方法报UserEntity仓库未找到错误

问题场景

基于NestJS+TypeORM连接PostgreSQL的项目中,执行UsersSeed数据种子方法时,数据可正常写入数据库,但操作完成后抛出如下错误:

No repository for "UserEntity" was found. Looks like 
this entity is not registered in current "default" connection? +114ms
RepositoryNotFoundError: No repository for "UserEntity" was found. Looks like this entity is not registered in current "default" connection?
    at RepositoryNotFoundError.TypeORMError [as constructor] (E:\Projects\...\src\error\TypeORMError.ts:7:9)
相关代码说明
  • 种子方法实现:方法内通过传入的Connection实例获取UserEntity、MediaEntity对应的仓库,执行查询、写入、更新操作,代码如下:
import { MediaEntity } from '../entities/media.entity';
import { Connection, Equal } from 'typeorm';
import { UserEntity } from '../entities/user.entity';
import { Helper } from '../services/helper';

export default async function UsersSeed(connection: Connection) {
  const repository = connection.getRepository(UserEntity);

  const data: Partial<UserEntity> = {
    firstName: 'tesFName',
    lastName: 'testLNsmr',
    password: 'fafafa',
    email: 'testmail@mail.com',
    createdAt: Helper.dateToUTC(new Date())
  };

  let user = await repository.findOne({ email: data.email });

  console.log("19");
  console.log(user);

  if (!user) {
    const entity = Helper.createEntity(UserEntity, data);
    console.log("23");
    user = await repository.save(entity);
    console.log("25");
  } else {
    console.log("27");
    await repository.update(user.id, {
      firstName: data.firstName,
      lastName: data.lastName
    });

    console.log("33");
  }

  console.log("36");

  const mediaRepository = connection.getRepository(MediaEntity);
  await mediaRepository.update({ user: Equal(null) }, { user: user });

  return user;
}
  • 根模块配置:app.module.ts中TypeORM通过forRootAsync异步加载配置,配置逻辑由OptionsService提供,代码如下:
@Module({
  imports: [
    ServeStaticModule.forRoot({
      rootPath: join(__dirname, 'uploads')
    }),
    TypeOrmModule.forRootAsync({
      useFactory: async (optionsService: OptionsService) =>
        optionsService.typeOrmOptions(),
      imports: [OptionsModule],
      inject: [OptionsService]
    }),
    OptionsModule,
    MediaModule,
    AuthModule,
    PlaceModule,
    RepositoryModule,
    ServicesModule
  ],
  controllers: [],
  providers: []
})
  • 实体模块配置:src/entities/entities.module.ts中已通过TypeOrmModule.forFeature注册包含UserEntity在内的所有实体并导出,代码如下:
const entities = [
  UserEntity,
  MediaEntity,
  PlaceEntity,
  DownloadRestrictionEntity,
  MediaInfoEntity
];

@Module({
  imports: [TypeOrmModule.forFeature(entities)],
  exports: [TypeOrmModule.forFeature(entities)]
})
export class EntitiesModule {
}
  • TypeORM连接配置:src/options/options.service.ts中entities采用通配符匹配目录下所有.entity后缀的文件,代码如下:
@Injectable()
export class OptionsService {
  constructor(
    private service: ConfigService<IEnvironmentVariables>
  ) {
  }
 public typeOrmOptions(): TypeOrmModuleOptions {
    const environment = process.env.NODE_ENV ? process.env.NODE_ENV : '';
    const directory = this.directory();
    return {
      type: 'postgres',

      host: this.service.get('POSTGRES_HOST'),
      port: this.service.get('POSTGRES_PORT'),
      username: this.service.get('POSTGRES_USER'),
      password: this.service.get('POSTGRES_PASSWORD'),
      database: this.service.get('POSTGRES_DATABASE'),
      synchronize: false,
      migrationsRun: this.service.get('RUN_MIGRATIONS'),
      keepConnectionAlive: this.isTest(),

      entities: [`${directory}/**/*.entity${environment ? '{.ts,.js}' : '{.js, .ts}'}`],

      migrationsTableName: 'migrations',
      migrations: [`${directory}/migrations/*.ts`],

      cli: {
        migrationsDir: 'src/migrations'
      }
    }
  }
}
故障原因
  1. 实体匹配glob语法错误:entities配置项的通配符规则存在明显语法问题,非环境分支的后缀匹配{.js, .ts}逗号后存在多余空格,不符合glob多匹配项的语法要求,导致.ts后缀的实体文件无法被正确扫描注册,开发环境ts-node运行时会出现实体注册不全的问题。

注意:glob多匹配项语法要求大括号内的选项之间仅用逗号分隔,不能加空格,否则会被识别为带空格的非法文件后缀,导致匹配失效。

  1. 根模块未加载实体模块:app.module.ts的imports列表中没有引入已经编写好的EntitiesModule,导致TypeOrmModule.forFeature注册的实体仓库没有在根作用域加载,框架执行生命周期收尾逻辑时无法获取到对应仓库实例。
  2. 连接保活逻辑缺陷:keepConnectionAlive配置仅在测试环境返回true,种子脚本执行完成后应用触发关闭流程会主动销毁数据库连接,此时如果还有后置逻辑(如关联字段校验、日志钩子、资源回收操作)尝试访问仓库,就会在业务操作完成后抛出仓库找不到的错误。
修复方案
  • 修正实体匹配的glob规则,去掉多余的环境分支判断和大括号内的空格,直接使用兼容ts、js后缀的匹配规则,将原有entities配置替换为:
    entities: [`${directory}/**/*.entity.{ts,js}`],
    
  • 在根模块app.module.ts的imports数组中添加EntitiesModule,确保forFeature注册的所有实体仓库在全局作用域正常加载。
  • 调整keepConnectionAlive配置逻辑,种子执行、开发环境下也开启连接保活,或者在种子方法逻辑全部执行完成、所有异步操作收尾后,再主动触发连接关闭,避免连接提前销毁。
  • 如果是独立运行的种子脚本,不要手动创建Connection实例,通过NestJS的应用上下文获取Connection对象,确保所有模块、实体都完成初始化注册后再执行种子逻辑。

内容的提问来源于stack exchange,提问作者Muhammad Arslan Jamshaid

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 04:31:11