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

TypeORM+NestJS查询User时无法获取关联Shop实体的问题求助

问题:TypeORM + NestJS 一对一关联查询未返回关联实体

我使用TypeORM和NestJS搭建服务,User类与Shop类为一对一关系,外键shopId存储在User表中。但调用查询方法获取User时,关联的Shop对象并未被返回,仅得到User自身字段,求问题原因及解决办法。

User类代码

@Entity()
export class User {
  @PrimaryGeneratedColumn()
  id: number;
  @Column('text')
  name: string;
  @Column('text')
  email: string;
  @Column('text')
  phoneNumber: string;
  @Column('text')
  password: string;
  @Column('boolean')
  isAdmin: boolean;

  @OneToOne(() => Shop, (shop) => shop.user)
  @JoinColumn()
  shop: Shop;

  constructor(
    name: string,
    email: string,
    phoneNumber: string,
    password: string,
  ) {
    this.name = name;
    this.email = email;
    this.phoneNumber = phoneNumber;
    this.password = password;
  }
}

Shop类代码

export class Shop {
  @PrimaryGeneratedColumn()
  id: number;
  @Column()
  name: string;

  @OneToOne(() => User, (user) => user.shop)
  user: User;
  @OneToMany(() => Order, (order) => order.shop)
  orders: Order[];
  @OneToMany(() => Product, (product) => product.shop)
  products: Product[];

  constructor(name: string) {
    this.name = name;
  }
}

UserService查询代码

export class UserService {
  constructor(
    @InjectRepository(User)
    private userRepository: Repository<User>,
    private dataSource: DataSource,
  ) {}
  
  findOneByPhoneNumber(phoneNumber: string): Promise<User> {
    return this.userRepository.findOneBy({ phoneNumber });
  }
  ...
}

当前返回结果

{
  "name": "test",
  "email": "test@gmail.com",
  "phoneNumber": "+251912345678",
  "password": "$2b$10$Q5FR7cleRkJebMPy.cPWIuPLQrNTMB3kxXWXPiRlFH99U4WfFqyd6",
  "id": 1,
  "isAdmin": false
}

问题原因及解决办法

1. Shop类缺少@Entity()装饰器

TypeORM无法识别未添加@Entity()的类为数据库实体,导致关联映射完全失效。必须给Shop类补上该装饰器:

@Entity() // 添加这个装饰器
export class Shop {
  @PrimaryGeneratedColumn()
  id: number;
  @Column()
  name: string;

  @OneToOne(() => User, (user) => user.shop)
  user: User;
  @OneToMany(() => Order, (order) => order.shop)
  orders: Order[];
  @OneToMany(() => Product, (product) => product.shop)
  products: Product[];

  constructor(name: string) {
    this.name = name;
  }
}

2. 查询未显式加载关联实体

TypeORM默认不会自动加载关联实体,且findOneBy是简化查询方法,不支持关联加载配置。需要改用findOne并指定relations参数,或使用QueryBuilder:

方式一:使用findOne + relations

findOneByPhoneNumber(phoneNumber: string): Promise<User> {
  return this.userRepository.findOne({
    where: { phoneNumber },
    relations: ['shop'], // 指定要预加载的关联实体
  });
}

方式二:使用QueryBuilder(更灵活,适合复杂查询)

findOneByPhoneNumber(phoneNumber: string): Promise<User> {
  return this.userRepository
    .createQueryBuilder('user')
    .leftJoinAndSelect('user.shop', 'shop')
    .where('user.phoneNumber = :phoneNumber', { phoneNumber })
    .getOne();
}

完成以上修改后,查询User时就能同时返回关联的Shop对象了。


内容的提问来源于stack exchange,提问作者Ameen Oumer

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 19:21:06