如何正确更新Typeorm中的实体关系

问题描述 投票:0回答:1

我有一个基本的用户表,他们可以在其中熟练掌握各种乐器。我无法弄清楚制作基本

updateUser
功能的正确方法,他们可以在该功能中更新用户信息,以及使用 Typeorm 和 MySQL 数据库的仪器熟练程度。

用户类别

@Entity()
@ObjectType()
export class User extends BaseEntity {

  public constructor(init?:Partial<User>) {
      super();
      Object.assign(this, init);
  }

  @Index({ unique: true})
  @Column()
  email: string;

  @Index({ unique: true})
  @Column()
  username: string;

  @Column()
  @HideField()
  password: string;

  @Column({
      nullable: true
  })
  profilePicture?: string;

  @Index({ unique: true})
  @Column()
  phoneNumber: string;

  //Lazy loading
  @OneToMany(() => UserInstrument, p => p.user, {
      cascade: true
  })
  instruments?: Promise<UserInstrument[]>;
}

用户仪器类

@Entity()
@ObjectType()
export class UserInstrument extends BaseEntity {

  public constructor(init?:Partial<UserInstrument | InstrumentProficiencyInput>) {
      super();
      Object.assign(this, init);
  }

  @Column({
      type: 'enum',
      enum: Instrument
  })
  instrument : Instrument

  @Column()
  proficiency : number;

  @JoinColumn()
  @HideField()
  userId : number;

  @ManyToOne(() => User, p => p.instruments)
  @HideField()
  user : User;
}

现在使用预定义工具创建新用户不再是问题。我只需插入一个新用户,它就会自动填充相应表格的

Id
UserId
字段。

  async create(request: RegisterUserInput) : Promise<boolean>{
    const user        = new User();
    user.username     = request.username;
    user.password     = request.password;
    user.phoneNumber  = request.phoneNumber;
    user.email        = request.email;
    user.instruments  = Promise.resolve(request.instruments?.map(p => new UserInstrument(p)));

    const result = await this.usersRepository.save(user);
}

问题

现在,每当我执行类似于更新用户/仪器表的操作时,我都会收到

"ER_BAD_NULL_ERROR: Column 'userId' cannot be null"
异常

  async updateUser(request: UpdateUserInput, id : number): Promise<boolean> {
    var user = new User(classToPlain(request));
    user.id = id;
    user.instruments = Promise.resolve(request.instruments?.map(p => new UserInstrument(p)));

    (await user.instruments)?.forEach(p => p.userId = id);

    await this.usersRepository.save(user);

    return true;
}

此代码生成以下异常

code:'ER_BAD_NULL_ERROR'
errno:1048
index:0
message:'ER_BAD_NULL_ERROR: Column 'userId' cannot be null'
name:'QueryFailedError'
parameters:(2) [null, 8]
query:'UPDATE `user_instrument` SET `userId` = ? WHERE `id` = ?'
sql:'UPDATE `user_instrument` SET `userId` = NULL WHERE `id` = 8'
sqlMessage:'Column 'userId' cannot be null'
sqlState:'23000'
stack:'QueryFailedError: ER_BAD_NULL_ERROR: Column 'userId' cannot be null

即使当我检查用户对象时,我可以看到

userId
字段设置正确

__has_instruments__:true
__instruments__:(1) [UserInstrument]
    0:UserInstrument {created: '2020-11-29 02:46:10', instrument: 'Guitar', proficiency: 5, userId: 30}
length:1

那么我做错了什么?是否有更首选的方法来更新用户仪器表,而无需直接访问仪器存储库?我不确定为什么我的创建方法中的初始

save
有效,但更新时不起作用。

javascript typescript lazy-loading typeorm
1个回答
1
投票

在更新任何项目时不要使用

save
方法,当 id 不存在时它会创建一个新记录,尽管在这种情况下它存在,我仍然更喜欢 typeorm 的
update
方法。代码会是这样的

async updateUser(request: UpdateUserInput, id: number): Promise<boolean> {
    // Convert instruments to UserInstrument entities
    const userInstruments = request.instruments?.map(p => {
        const userInstrument = new UserInstrument(p);
        userInstrument.userId = id; // Set userId for each instrument
        return userInstrument;
    });

    // Perform the update using the update method
    await this.usersRepository.update(id, {
        ...classToPlain(request),
        instruments: userInstruments ? Promise.resolve(userInstruments) : undefined
    });

    return true;
}
© www.soinside.com 2019 - 2024. All rights reserved.