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

Apollo+TypeORM报错:非空字段Member.memberType返回Null

问题解决:Cannot return null for non-nullable field Member.memberType

核心问题根源

你的MemberType实体存在关联字段定义错误,导致TypeORM关联映射逻辑混乱——尽管控制台输出看起来包含memberType数据,但GraphQL解析实体时无法正确识别关联关系,最终触发非空字段报错。同时还有几处代码细节需要修正。

1. 修复MemberType实体的错误定义

在MemberType中,你错误地将@OneToMany关联字段命名为memberType,且将类型声明为string,违反了TypeORM关联规则:

  • @OneToMany关联字段必须是对应实体的数组类型(Member[])
  • 字段名不能与关联目标的字段名重复,避免映射冲突

修正后的MemberType实体:

/** ID number of a member type. */
@PrimaryGeneratedColumn('increment')
@Field()
id!: number;

/** 该成员类型对应的所有成员(OneToMany关联) */
@OneToMany(() => Member, (member) => member.memberType)
@Field(() => [Member], { nullable: true }) // 根据业务需求设置是否可选
members!: Member[];

/** 成员类型名称(你原本需要的字符串字段) */
@Field()
typeName!: string; // 替换原来错误的`memberType`字符串字段

2. 修正Member实体的反向关联引用

确保Member的@ManyToOne关联中,反向引用指向MemberType中正确的关联字段:

/** Reference to type of member. */
@ManyToOne(() => MemberType, (memberType) => memberType.members, { eager: true })
@Field(() => MemberType)
memberType!: MemberType;

3. 修正memberUpdate解析器的无效代码与查询逻辑

  • 移除无意义的Member.save;代码,这行未执行任何实际操作
  • 改用findOne替代findOneBy,确保eager: true配置生效(部分场景下findOneBy不会自动触发eager加载)

修正后的memberUpdate片段:

/** Update a member with new details */
@Mutation(() => Member, {nullable: true })
async memberUpdate(
  @Arg('input') input: MemberUpdateInput,
  @Ctx() { request }: AppContext
): Promise<Member | null> {
  input.throwIfInvalid();
  const { userID } = request.session;
  const existingUser = await User.findOneBy({ id: userID });
  if (!existingUser) {
    throw new AuthenticationError;
  }
  const existingMember = await Member.findOneBy({ id: input.id });
  if (!existingMember) {
    throw new FormError({
      control: [ `Member '${input.firstName} ${input.lastName}' does not exist!` ]
    });
  }
  const memberTypeInput = new IdNumberInput();
  memberTypeInput.id = input.memberType.id;
  const memberType = await new MemberTypeResolver().memberTypeDetails(memberTypeInput);
  await Member.update({ id: input.id }, {
    firstName: input.firstName,
    githubUrl: input.githubUrl,
    lastName: input.lastName,
    linkedinUrl: input.linkedinUrl,
    memberType: memberType,
    personalUrl: input.personalUrl,
    photoUrl: input.photoUrl
  });
  // 改用findOne确保eager加载关联数据
  const updatedMember = await Member.findOne({
    where: { id: input.id }
  });
  console.log(updatedMember?.memberType);
  if (!updatedMember) {
    throw new ServerError;
  }

  return updatedMember;
}

4. 验证数据库数据一致性

检查数据库中member表的memberTypeId字段:

  • 确保所有member记录的memberTypeId不为null
  • 确认每个memberTypeId在memberType表中都有对应存在的记录

如果存在memberTypeId为null的记录,即使设置了eager: true,查询时也会返回null,触发非空字段报错。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 23:26:02