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

NestJS关联实体获取用户ID时出现undefined错误,求解决方案

问题:激活钱包时无法读取关联用户的id属性

实体关联定义

User实体

@OneToMany(() => Wallet, wallet => wallet.user)
wallets: Wallet[];

Wallet实体

@ManyToOne(() => User, user => user.wallets)
user: User;

钱包激活服务代码

async walletActivation(walletId: number): Promise<Boolean> {
  const wallet = await this.walletsRepo.findOneBy({ id: walletId })
  if (!wallet) throw new NotFoundException('Wallet Not Found')

  wallet.isActive = 0; // 先确保钱包未激活
  
  console.log("------");
  const user = await this.usersService.findOneById(wallet.user.id); // 此处报错
  if (!user) throw new NotFoundException('User associated with the wallet not found.')
  if (!user.isVerified) throw new BadRequestException('User account is not verified.')

  wallet.isActive = 1;

  await this.walletsRepo.save(wallet);
  return true;
}

控制器端点代码

@Post('activateWallet/:id')
async walletActivation(@Param('id') id: string) {
  try {
    await this.walletsService.walletActivation(+id);
    return { message: 'Wallet activated successfully' };
  } catch (error) {
    console.error('Error activating wallet:', error);

    if (error instanceof NotFoundException) {
      throw new HttpException('Wallet or user not found', HttpStatus.NOT_FOUND);
    } else if (error instanceof BadRequestException) {
      throw new HttpException('User is not verified', HttpStatus.BAD_REQUEST);
    } else {
      throw new HttpException('Wallet cannot be activated', HttpStatus.BAD_REQUEST);
    }
  }
}

错误信息

Error activating wallet: TypeError: Cannot read properties of undefined (reading 'id')
    at WalletsService.walletActivation (G:\abood\IT\Courses\Projects\NestJS\Wallet System\wallet-system\src\wallets\wallets.service.ts:33:66)
    at process.processTicksAndRejections (node:internal/process/task_queues:105:5)
    at async WalletsController.walletActivation (G:\abood\IT\Courses\Projects\NestJS\Wallet System\wallet-system\src\wallets\wallets.controller.ts:32:7)

解决建议

1. 查询钱包时关联加载User实体

问题根源是findOneBy默认不会自动加载关联的user实体,导致wallet.user为undefined。修改查询代码,显式指定加载关联:

// 替换原findOneBy代码
const wallet = await this.walletsRepo.findOne({
  where: { id: walletId },
  relations: ['user'] // 关联加载user实体
});

或者使用QueryBuilder更灵活:

const wallet = await this.walletsRepo.createQueryBuilder('wallet')
  .leftJoinAndSelect('wallet.user', 'user')
  .where('wallet.id = :walletId', { walletId })
  .getOne();

2. 增加空值检查(可选但推荐)

即使关联加载后,仍可能存在钱包未关联用户的情况,建议增加检查:

if (!wallet.user) throw new NotFoundException('Wallet has no associated user.');
const user = await this.usersService.findOneById(wallet.user.id);

3. 谨慎使用eager加载(不推荐全局使用)

如果确实需要每次查询Wallet都自动加载User,可以在Wallet实体的@ManyToOne装饰器中添加eager: true,但这种方式会增加不必要的数据库查询,仅在全局需要时使用:

@ManyToOne(() => User, user => user.wallets, { eager: true })
user: User;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 23:48:26