如何解决TypeORM GetRepository的“Cannot read properties of undefined”错误
错误日志
[Nest] 171 - 2022年8月31日 晚上8:35:42 ERROR [ExceptionHandler] 无法读取未定义的属性(读取'getRepository') tenant-node |
TypeError: 无法读取未定义的属性(读取'getRepository') tenant-node | 在 InstanceWrapper.useFactory [as
metatype]
(/var/www/app/src/infrastruture/providers/tenant.provider.ts:6:56)
tenant-node | 在 Injector.instantiateClass
(/var/www/app/node_modules/@nestjs/core/injector/injector.js:343:55)
tenant-node | 在 callback
(/var/www/app/node_modules/@nestjs/core/injector/injector.js:53:45)
tenant-node | 在 processTicksAndRejections
(node:internal/process/task_queues:95:5) tenant-node | 在
Injector.resolveConstructorParams
(/var/www/app/node_modules/@nestjs/core/injector/injector.js:132:24)
tenant-node | 在 Injector.loadInstance
(/var/www/app/node_modules/@nestjs/core/injector/injector.js:57:13)
tenant-node | 在 Injector.loadProvider
(/var/www/app/node_modules/@nestjs/core/injector/injector.js:84:9)
tenant-node | 在 async Promise.all (index 3) tenant-node |
在 InstanceLoader.createInstancesOfProviders
(/var/www/app/node_modules/@nestjs/core/injector/instance-loader.js:47:9)
tenant-node | 在
/var/www/app/node_modules/@nestjs/core/injector/instance-loader.js:32:13
问题根源
错误指向tenant.provider.ts中dataSource为undefined,核心原因是依赖注入配置错误,导致NestJS无法正确注入DATA_SOURCE实例。
解决方案
1. 修正tenant.provider.ts的注入属性名
NestJS的提供者配置中,用于声明依赖的属性是小写的inject,而非大写的Inject。原代码中大写的属性名会被Nest忽略,导致dataSource无法被注入。
修正后的tenant.provider.ts:
import { DataSource, Repository } from "typeorm"; import { TenantSchema } from "../db/TenantSchemas.schema"; export const TenantProviders = [{ provide: 'TENANT_REPOSITORY', useFactory: (dataSource: DataSource) => dataSource.getRepository(TenantSchema), inject: ['DATA_SOURCE'] // 改为小写的inject }, ];
2. 确保DBTenant模块正确导出数据库提供者
DBTenant模块必须将dbProviders加入providers数组,并通过exports导出,这样AppModule才能访问到DATA_SOURCE这个依赖。
示例DBTenant模块代码:
import { Module } from '@nestjs/common'; import { dbProviders } from '../db.provider'; @Module({ providers: [...dbProviders], exports: [...dbProviders], // 必须导出,否则其他模块无法注入DATA_SOURCE }) export class DBTenant {}
3. 验证appDataSource配置正确性
确保app.source.ts中的DataSource实例配置完整,包含实体、数据库连接信息等必要参数:
import { DataSource } from 'typeorm'; import { TenantSchema } from './TenantSchemas.schema'; export const appDataSource = new DataSource({ type: 'mysql', // 根据你的数据库类型修改 host: process.env.DB_HOST, port: parseInt(process.env.DB_PORT), username: process.env.DB_USERNAME, password: process.env.DB_PASSWORD, database: process.env.DB_NAME, entities: [TenantSchema], synchronize: process.env.NODE_ENV === 'development', // 开发环境可开启,生产环境建议关闭 });
验证
修改完成后重启项目,若配置正确,DATA_SOURCE会被成功注入到TENANT_REPOSITORY的工厂函数中,getRepository方法即可正常调用。
内容的提问来源于stack exchange,提问作者Maria Lima

