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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 23:15:04