LikeCount와 같은 테이블의 number 칼럼에 +1 혹은 -1을 할 일이 생기는 경우, +1을 하는 API를 새로 구성하는 것 보다 Like 테이블에 row가 추가될 때마다 SubScriber에서 트랜잭션을 열고, +1을 추가하는 것이 프론트의 api 호출 빈도를 줄일 수 있다는 점에서 장점이 있다고 생각하였다.
+1의 경우, TypeORM afterInsert( )를 사용하여 insertEvent가 해당 테이블에서 발생시 number +=1을 하는 방식으로 작성하여, 정상적으로 likeCount 칼럼의 값에 +1이 되는 것을 확인하였는데, -1의 경우, 테이블에서 해당 정보가 삭제되더라도 removeEvent가 row가 삭제된 것을 체크하지않아 -=1이 되지않는 문제가 발생하였다.
원인
Delete 메소드를 활용하는 REST api는 Service단에서 repository.delete({id})를 사용하여 id 값을 통해 해당 row를 삭제하는 경우가 많았다. 관련 TypeORM Issue를 살펴보면 repository.delete()를 사용하지 말고, repository.remove()를 사용하면 removeEvent가 작동한다고 되어있다.
해결방법
해당 removeEvent가 작동해야되는 Delete 메소드 API의 Service 부분을 repository.delete({id})에서 repository.remove(repository)의 방식으로 변경하였다.
.delete()를 사용할 때는 아래와 같이 테이블에서 검색하지않고, 바로 id값만을 통해 삭제하였다.
deleteLikeById(id: number) {
return this.repository.delete({ id });
}
.remove의 경우, 아래와 같이 테이블에서 id값을 통해 find를 해와서 불러온 해당 엔티티 자체를 삭제하는 방식으로 하였다.
async deleteLike(id: number) {
const like = await this.repository.findOne({ id });
this.repository.remove(like);
}
해결된 이유
평소라면 "해결했다~"하고 끝내겠지만, .remove와 .delete 어떻게 보면 '삭제'라는 동일한 기능을 하는 함수를 굳이? typeorm에서 두 가지로 나눠서 구현해놓은 이유와 .remove와 .delete의 차이점, 왜 removeEvent는 delete() 사용시 작동하지않는지 모르겠어서 이에 대해 알아보았다. TypeORM 깃헙의 repository API 문서를 확인해보면 아래와 같이 설명되어있다.
repository.remove( )
한 트랜잭션안에 주어진 Entity나 Entitiy Array를 삭제한다. 삭제된 Entity 혹은 Entities를 리턴합니다.
repository.delete( )
주어진 id, ids 또는 조건으로 Entitiy를 삭제합니다.
위의 두 설명만 봐도 왜 removeEvent의 Entiity가 undefined였는지 이해가 되었다. .remove의 경우, 삭제하고 나서 해당 삭제된 Entity를 리턴하지만, .delete의 경우, 리턴하는 값 없이 삭제해버린다.
SubScriber afterRemove( )에서 removeEvent의 Entity가 notFound인 이유
LikeCount와 같은 테이블의 number 칼럼에 +1 혹은 -1을 할 일이 생기는 경우, +1을 하는 API를 새로 구성하는 것 보다 Like 테이블에 row가 추가될 때마다 SubScriber에서 트랜잭션을 열고, +1을 추가하는 것이 프론트의 api 호출 빈도를 줄일 수 있다는 점에서 장점이 있다고 생각하였다.
+1의 경우, TypeORM afterInsert( )를 사용하여 insertEvent가 해당 테이블에서 발생시 number +=1을 하는 방식으로 작성하여, 정상적으로 likeCount 칼럼의 값에 +1이 되는 것을 확인하였는데, -1의 경우, 테이블에서 해당 정보가 삭제되더라도 removeEvent가 row가 삭제된 것을 체크하지않아 -=1이 되지않는 문제가 발생하였다.
원인
Delete 메소드를 활용하는 REST api는 Service단에서 repository.delete({id})를 사용하여 id 값을 통해 해당 row를 삭제하는 경우가 많았다. 관련 TypeORM Issue를 살펴보면 repository.delete()를 사용하지 말고, repository.remove()를 사용하면 removeEvent가 작동한다고 되어있다.
해결방법
해당 removeEvent가 작동해야되는 Delete 메소드 API의 Service 부분을 repository.delete({id})에서 repository.remove(repository)의 방식으로 변경하였다.
.delete()를 사용할 때는 아래와 같이 테이블에서 검색하지않고, 바로 id값만을 통해 삭제하였다.
.remove의 경우, 아래와 같이 테이블에서 id값을 통해 find를 해와서 불러온 해당 엔티티 자체를 삭제하는 방식으로 하였다.
해결된 이유
평소라면 "해결했다~"하고 끝내겠지만, .remove와 .delete 어떻게 보면 '삭제'라는 동일한 기능을 하는 함수를 굳이? typeorm에서 두 가지로 나눠서 구현해놓은 이유와 .remove와 .delete의 차이점, 왜 removeEvent는 delete() 사용시 작동하지않는지 모르겠어서 이에 대해 알아보았다. TypeORM 깃헙의 repository API 문서를 확인해보면 아래와 같이 설명되어있다.
repository.remove( )
한 트랜잭션안에 주어진 Entity나 Entitiy Array를 삭제한다. 삭제된 Entity 혹은 Entities를 리턴합니다.
repository.delete( )
주어진 id, ids 또는 조건으로 Entitiy를 삭제합니다.
위의 두 설명만 봐도 왜 removeEvent의 Entiity가 undefined였는지 이해가 되었다. .remove의 경우, 삭제하고 나서 해당 삭제된 Entity를 리턴하지만, .delete의 경우, 리턴하는 값 없이 삭제해버린다.
결론은 "공식 깃헙에서 문서를 잘 읽어보자" 였다.참고) https://github.com/typeorm/typeorm/blob/master/docs/repository-api.md
'개발 > TypeORM' 카테고리의 다른 글