iamkanguk.dev

[NestJS] Repository Pattern에서 find(findOne)을 사용할 때 주의해야 할 사항! (where condition with null value) 본문

Framework/NestJS

[NestJS] Repository Pattern에서 find(findOne)을 사용할 때 주의해야 할 사항! (where condition with null value)

iamkanguk 2023. 11. 10. 04:37
async findMarkOnSpecificId(
    mark: MarkDto,
  ): Promise<GetMarkDetailByIdResponseDto> {
    const queryRunner = this.dataSource.createQueryRunner();
    await queryRunner.connect();
    await queryRunner.startTransaction();

    try {
      const markCategoryName = await this.markCategoryRepository.findOne({
        select: {
          title: true,
        },
        where: {
          id: mark.getMarkCategoryId,
          status: StatusColumnEnum.ACTIVE,
        },
      });

      // metadata 부분 조회하기
      const markMetadatas =
        await this.markMetadataRepository.selectMarkMetadatasByMarkId(
          mark.getId,
        );

      await queryRunner.commitTransaction();
      return GetMarkDetailByIdResponseDto.from(markMetadatas);
    } catch (err) {
      this.logger.error(`[findMarkOnSpecificId - transaction error] ${err}`);
      await queryRunner.rollbackTransaction();
      throw err;
    } finally {
      await queryRunner.release();
    }
  }

 

위의 코드는 Query Parameter로 들어온 Mark의 ID를 가지고 Mark를 조회하는 로직이 있는 메서드이다. 위의 코드에서 findOne을 주의 깊게 보자!

 

일단 Mark는 MarkDto라는 타입을 가지고 있다. Mark는 카테고리를 가질 수도 있고 가지지 않을 수도 있기 때문에 nullable한 값이다.

이후 mark 변수에서 getter를 통해 markCategoryId를 가져와서 where 조건에 넣어줬는데...!

 

처음에는 markCategoryName 변수가 null로 할당될 줄 알았다. 하지만 보니까 값이 출력이 되는 것이다. 확인해보니까 find 메서드를 사용하니까 그냥 where true로 되어서 모든 카테고리 값들이 나오는 것이었다. 그래서 findOne은 출력되는 값들 중에 제일 위의 값이 출력이 된 것이었다.

 

우리는 이런 상황을 방지해야 한다. 위의 문제를 파악하지 못하고 그대로 코드를 작성했더라면 문제가 분명히 발생했을 것이다.

그래서 위의 상황을 어떻게 해결할 수 있느냐?

 

TypeORM의 Equal 메서드를 사용하면 된다. id: mark.getMarkCategoryId 부분에서 Equal 메서드를 적용해주면 Filter가 정확히 적용이 되어서 정확하게 원하는 데이터를 얻을 수 있다. 물론 다른 방법도 있는 것 같으니 참고하는 것도 좋을 듯!

 

참고 자료

- https://orkhan.gitbook.io/typeorm/docs/find-options