728x90
현재 재직 중인 회사의 백엔드 코드 구조는 도메인 와 ORM 엔티티가 분리된 구조다. 각 레이어 간의 이동은 맵퍼를 통해서 변환해 이동하게 되는데, 이런 구조의 특징 상 MikroORM의 영속성 콘텍스트를 사용하기 어렵다. 그래서 각 영속성 계층에서는 영속성 콘텍스트에 변경된 내용이 있다면 바로 데이터베이스와 동기화하도록 구성된다.
그렇지만 오늘 문제가 된 테스트 코드는 데이터를 삭제 후 제대로 삭제가 됐는지 검증하는 테스트 코드로서 큰 고민 없이 코드를 작성했다.
it('The class should be deleted', async () => {
await courseRepository.delete(course);
const deletedCourse = await courseRepository.findOneById(course.id);
expect(deletedCourse.isNone()).toBe(true);
});
그리고 실제로 발행되는 SQL 역시 의도한 형태로 구성됐다. 하지만 테스트는 실패한다.
[query] begin
[query] delete from "courseware"."courses" where "id" in (1) [took 2 ms, 1 row affected]
[query] commit
Unit of work
MikroORM 공식 문서 "Unit of Work and Transactions"를 보면 하나의 작업 단위에서 여러 도메인에서 발생하는 조회/수정/삭제에 대해서 상태를 관리하고, 특정 시점에 일괄적으로 처리하는 방식을 의미한다.
MikroORM Unit of Work
MikroORM은 Unit of Work pattern을 활용해 엔티티를 관리하며 변경감지, 캐시, 연관 관계 처리 등 다양한 일을 개발자가 객체지향적으로 접근할 수 있도록 지원해 준다.
무엇이 문제였는가
앞서 설명했듯이 현재 진행 중인 프로젝트에서는 도메인과 ORM을 분리해서 사용한다. 따라서 계층 간의 이동에는 반듯이 도메인으로 변환하는 로직이 존재하는데, 이 변환된 객체가 IdentityMap에서 관리되는 객체가 동일하지 않기 때문에 삭제 시 IdentityMap에서 제거하는 작업이 누락된 것이다.
'메모' 카테고리의 다른 글
[8월 디버깅] 가짜 Nest.js 개발자 (0) | 2024.08.17 |
---|---|
[8월의 디버깅] 성능 테스트 (0) | 2024.08.14 |
NGINX reverse proxy (1) | 2024.05.19 |
틴타임즈 : 뉴스 10초 요약 회고 (0) | 2023.12.29 |
하이버네이트 공식 문서를 읽고 배운 점 (0) | 2023.12.29 |