개발 slecs

파트너 포털 주문내역 검색에서 수신자·작성자 누락 버그 수정

목차

partner-portal 주문내역 검색 화면에서 receiver_name(수신자명)과 creator(작성자) 두 필드가 검색 조건에 반영이 안 되는 버그를 잡았음. 증상 자체는 단순한데, 왜 안 잡히는지 파악하는 데가 더 오래 걸렸다. 변경 파일은 SQL 매퍼 1개. 근데 그 한 파일 안에서 조건절 처리와 집계 방식 둘 다 틀려 있었음.

왜 찾기 어려웠나

예외가 조용히 삼켜지고 있었다. 특정 검색 조건이 들어오면 분기가 스킵되는 구조였는데, 그 경우 로그에 아무것도 안 남음. 에러가 없으니 정상처럼 보이고, 결과가 그냥 비거나 일부만 나오는 식으로 나타남.

MyBatis 계열 SQL 매퍼를 쓸 때 흔히 보이는 패턴임. <if test="..."> 조건이 의도와 다르게 평가되거나, 동적 쿼리 조각이 붙었다 안 붙었다 하면서 WHERE절이 이상하게 조합되는 경우. 문제는 이게 실행 에러가 아니라 "결과가 없음"으로 나타난다는 거다. 로그에 exception stack trace가 없으니 보는 사람은 데이터가 원래 없는 건지, 쿼리가 틀린 건지 구분이 안 됨.

receiver_namecreator는 검색 조건에서 OR로 묶여야 하는 필드인데, 조건 분기가 누락돼서 해당 파라미터가 들어와도 WHERE절에 반영이 안 됐음. 이름으로 검색해도 전체 목록이 나오거나, 아예 빈 결과가 나오는 상황.

<!-- 수정 전: receiver_name, creator 조건 분기 없음 -->
<if test="keyword != null and keyword != ''">
    AND o.order_no LIKE CONCAT('%', #{keyword}, '%')
</if>

<!-- 수정 후: 수신자·작성자 조건 OR로 추가 -->
<if test="keyword != null and keyword != ''">
    AND (
        o.order_no    LIKE CONCAT('%', #{keyword}, '%')
        OR o.receiver_name LIKE CONCAT('%', #{keyword}, '%')
        OR o.creator       LIKE CONCAT('%', #{keyword}, '%')
    )
</if>

핵심은 검색 대상 컬럼을 OR로 묶어야 한다는 것. 조건 자체는 단순한데, 이걸 매퍼에서 빠뜨리면 서비스 레이어나 화면 쪽에서 파라미터를 아무리 잘 넘겨도 의미가 없어짐.

SQL 매퍼에서 자주 놓치는 패턴

동적 쿼리를 오래 관리하다 보면 이런 식의 누락이 생각보다 자주 일어남. 기능 추가할 때 Java 서비스 쪽이나 화면 쪽에는 파라미터가 잘 내려가는데, 매퍼에서 그 파라미터를 받아 쓰는 분기를 빠뜨리는 경우다. 컴파일 에러가 없으니 그냥 지나감.

상황 증상 원인
조건 분기 누락 검색해도 결과 없음 또는 전체 목록 반환 <if> 블록 미추가
NULL 체크 누락 파라미터 없을 때 WHERE절 깨짐 != null and != '' 조건 누락
집계 컬럼 누락 합계 숫자가 맞지 않음 GROUP BY / SUM 대상 누락
조인 미반영 특정 필드 항상 null 조인 조건 또는 SELECT절 누락

이번 케이스는 조건 분기 누락이 주원인이었는데, 검증 과정에서 집계 수치도 일부 맞지 않는 부분이 있어서 그 쪽도 함께 보정했음. 원인이 같은 레이어에 있으면 한 번에 확인하는 게 맞다.

수정하면서 챙긴 것들

해당 파라미터 분기 하나 추가하고 끝낼 수도 있었는데, 같은 매퍼 파일 안에 유사한 패턴으로 된 다른 쿼리가 있는지 먼저 훑었음. SQL 매퍼 파일은 관련 기능 쿼리들이 한 파일에 모여 있는 경우가 많아서, 한 쿼리에서 발견한 패턴이 다른 쿼리에도 반복돼 있을 가능성이 꽤 높다. 같은 파일에서 receiver_name 키워드로 검색해서, 어디는 조건에 있고 어디는 없는지 비교하는 식으로 확인. 빠진 곳은 함께 수정했음.

수정 후 검증은 버그 재현 순서 그대로 밟았음.

  • 수신자명으로 검색 - 결과가 정상적으로 필터링되는지 확인
  • 작성자명으로 검색 - 동일하게 확인
  • 두 필드가 서로 다른 주문에 있을 때 OR 조합으로 잘 나오는지 확인
  • 집계 숫자를 관련 화면과 cross-check

마지막 항목이 중요한 건, 검색 결과 개수나 합계가 다른 화면에서 보여주는 수치와 불일치하면 그 자체가 버그 신호이기 때문임. 동일 데이터를 다른 경로로 조회하는 화면이 여럿 있다면 그 숫자들은 당연히 맞아야 함. 맞지 않으면 어딘가 누락이 있다는 뜻.


버그를 하나 수정할 때마다 체감하는 건, SQL 매퍼는 타입 에러도 없고 런타임에 조용히 실패한다는 점에서 디버깅 비용이 꽤 높다는 거임. Java 코드는 컴파일 단계에서 걸리는 게 있지만 XML 매퍼는 없음. 그래서 신규 조건 추가할 때 파라미터만 넘기고 쿼리 쪽 반영을 빠뜨리는 실수가 생기기 쉬움. 이걸 방지하는 가장 현실적인 방법은, 파라미터를 추가했으면 매퍼에서 실제로 쓰고 있는지 같이 확인하는 습관을 코드 리뷰 단계에 박아 두는 것. 자동화된 테스트가 있으면 더 좋지만, 없는 상황에서는 개발 완료 직후 파라미터-쿼리 연결 여부를 수동으로 훑는 게 차선책임.

사내 서비스라도 주문, 결제, 정산 같은 숫자가 실제로 쓰이는 화면은 "대충 동작하는 것 같다"고 넘어가면 안 됨. 숫자 하나가 맞지 않으면 그 서비스를 매일 쓰는 담당자 입장에서는 시스템 자체를 못 믿게 됨. 신뢰가 한 번 흔들리면 복구하는 데 드는 비용이, 처음에 꼼꼼하게 확인했을 때보다 훨씬 크다. 엣지 케이스를 따지는 게 귀찮아 보여도, 결국 나중에 같은 버그로 다시 오는 시간이 더 비쌈.

커밋은 "SQL 매퍼 수신자·작성자 검색 조건 추가" 식으로 무엇을 바꿨는지보다, 왜 바꿨는지가 조금이라도 읽히도록 메시지를 남기려 노력함. 작은 커밋을 자주 하면 나중에 어느 변경에서 회귀가 생겼는지 찾기 훨씬 쉬워짐. 이번처럼 파일 1개만 건드리는 수정도 논리적으로 독립된 단위로 커밋을 쪼개는 습관을 유지 중.

댓글 0

첫 댓글 달아줘.