(TypeORM) @ BeforeUpdate의 실행 타이밍

SteadySlower·2025년 1월 20일
0

NestJS

목록 보기
1/1
post-thumbnail

문제점

User Entity 안에서 비밀번호를 변경할 때 해싱을 하기 위해서 아래와 같은 코드를 작성했다. 그런데 비밀번호를 변경해도 해싱이 되지 않았다? 왜 일까?

  @BeforeUpdate()
  async hashPasswordUpdate(): Promise<void> {
    try {
      this.password = await bcrypt.hash(this.password, 10);
    } catch (e) {
      console.log(e);
      throw new InternalServerErrorException();
    }
  }

원인

@BeforeUpdate가 동작하지 않는 일반적인 이유는 TypeORM의 동작 방식 때문이다. @BeforeUpdate는 전체 엔티티를 업데이트할 때만 트리거되고, 부분 업데이트(특정 컬럼만 업데이트)할 때는 실행되지 않는다.

해결 방법

  1. 서비스 레벨에서 전체 Entity를 저장하는 방식을 사용한다
async updateUser(userId: number, { password }: UpdateUserInput) {
  const user = await this.users.findOne({ where: { id: userId } });
  if (password) {
    user.password = password;
    // save()는 전체 엔티티를 저장하므로 @BeforeUpdate가 실행됨
    return this.users.save(user);
  }
  // ... 다른 업데이트 로직
}
  1. 또는 더 간단히 @BeforeUpdate 대신 setter를 사용한다
@Column()
@Field(() => String)
@IsString()
set password(value: string) {
  this.password = bcrypt.hashSync(value, 10);
}

첫 번째 방법을 추천한다. update() 대신 save()를 사용하면 Entity의 모든 라이프사이클 이벤트가 제대로 동작한다.

profile
백과사전 보다 항해일지(혹은 표류일지)를 지향합니다.

0개의 댓글