Nestjs TypeORM配置SnakeNamingStrategy后调用BaseEntity.save报字段不存在
问题原因
你遇到的报错核心是:TypeORM的BaseEntity自带的静态方法(create/save等)默认走全局独立的TypeORM实例配置,不会读取Nest框架中通过TypeOrmModule.forRoot注入的命名策略配置,所以SnakeNamingStrategy没有生效,执行SQL时直接把驼峰格式的属性名firstName当作数据库列名查询,但数据库中实际生成的列是蛇形格式的first_name,最终触发列不存在的报错。
解决方案
以下三个方案按推荐优先级排序:
方案1:改用Nest注入的Repository操作(最推荐,符合Nest依赖注入规范)
先在users.module.ts中注册实体:import { TypeOrmModule } from '@nestjs/typeorm'; import { User } from './users.entity'; @Module({ imports: [TypeOrmModule.forFeature([User])], providers: [UserService], }) export class UserModule {}再修改
users.service.ts,用注入的Repository替代BaseEntity静态方法:import { Injectable } from '@nestjs/common'; import { InjectRepository } from '@nestjs/typeorm'; import { Repository } from 'typeorm'; import { User } from './users.entity'; @Injectable() export class UserService { constructor( @InjectRepository(User) private readonly userRepository: Repository<User>, ) {} create(createUserInput: CreateUserServiceInput) { const user = this.userRepository.create(createUserInput); return this.userRepository.save(user); } }该方案下命名策略会自动生效,无需额外配置。
方案2:手动绑定DataSource到BaseEntity
如果一定要保留BaseEntity静态方法的写法,可以在AppModule初始化时把Nest管理的DataSource实例绑定到BaseEntity上:import { Module, OnModuleInit } from '@nestjs/common'; import { DataSource } from 'typeorm'; import { BaseEntity } from 'typeorm'; import { SnakeNamingStrategy } from 'typeorm-naming-strategies' @Module({ imports: [ ConfigModule.forRoot({ isGlobal: true }), TypeOrmModule.forRoot({ namingStrategy: new SnakeNamingStrategy() }), GraphQLModule.forRoot({ autoSchemaFile: 'schema.gql' }), UserModule, ], }) export class AppModule implements OnModuleInit { constructor(private dataSource: DataSource) {} async onModuleInit() { BaseEntity.useDataSource(this.dataSource); } }方案3:手动指定列名(不推荐,冗余代码多)
不想调整现有逻辑的话,可以给每个字段手动指定蛇形格式的数据库列名:@Column({ name: 'first_name', length: 20, nullable: false }) firstName: string @Column({ name: 'last_name', length: 25, nullable: false }) lastName: string
内容的提问来源于stack exchange,提问作者Jack
相关产品推荐
相关产品推荐

