전체 글
[Java] List -> Map 변환은 신중하자
List를 Map으로 변형해야할 일이 있어서 이렇게 처리했다고 해보자. List foods = Arrays.asList( new Food("Coke", 1500), new Food("Beer", 3000), new Food("Coke", 1600), new Food("Snack", 4000)); Map foodMap = foods.stream() .collect(Collectors.toMap(Food::getName, Food::getPrice)); 코드를 실행하보면 Duplicate Key 예외가 발생한다. 위 예제야 뻔히 보이지만 수천, 수만건의 데이터 중 단 하나의 중복이 있었다면 사전에 발견하지 못했을 것이다. 비즈니스적으로는 중복이 없어야 맞는 것이라도, 예상할 수 없었던 예외 케이스가 늘 발..
저는 지극히 평범한 개발자입니다
켄트 백의 테스트 주도 개발(Test Driven Development)을 읽어보면 뜻밖에도 켄트 백 본인은 너무도 평범한 개발이기 때문에 테스트를 중요시한다는 내용이 나온다. 그 구절을 보고 개발자로서는 안도하지 않을 수 없다. 나 역시 수 많은 평범한 개발자 중 하나이고, 평범한 개발자라면 언제라도 실수와 의도하지 않은 Side Effect로 인한 문제를 겪을 수 있기에 다양한 안전장치를 두는 것이 마땅하다는 의미이기 때문이다. 켄트 백이 보증한다. 지금의 팀에 합류하고나서 팀에 세가지가 비어있다는 생각을 했다. 1. 문서화 2. 테스트 코드 3. APM Tool 우리가 평범한 개발자이기 때문에 당연히 갖추고 있어야할 이 세 가지 필수적인 요소들이 현재 팀에는 부족했다. 우선 내가 갑자기 굴러들어온 ..
Spring Data JPA @Query 사용시 주의점(JPA 버그)
이전 회사에서 새벽에 돌아야할 배치가 안돌아서 난리가 났던 적이 한번 있었는데 알고보니 쿼리 하나가 몇 시간째 돌고 있었다. 어쨌든 원인을 빨리 찾아서 고치긴 했는데 분석을 해보니 Spring Data JPA(2.6.2 기준)에 문제가 있었다. @Query annotaion을 쓰면서 Paging 처리를 할 때 발생할 수 있는 이슈인데, 다음 번에 깊게 파볼 생각으로 남겨두었던게 갑자기 생각이 나서 좀 들여다보았다. 상황을 재현해보면 아래와 같다. public interface ProductJpaRepository extends JpaRepository { @Query(value = "select id, name from product where name = :productName", nativeQuery..
[개발일기] 재택 근무 2년 간의 회고
2020년 초. 코로나 바이러스가 전 세계를 뒤덮었다. 곧 상황이 안좋아져서 회사에서도 전사 재택 근무라는 초유의 결정이 내려졌고, 정말 뜻밖에도 2년이 지난 지금까지(중간에 회사를 한번 옮겼음에도) 그 생활이 이어지게 되었다. 처음에는 출퇴근을 하지 않아도 된다는 생각에 막연히 좋기도 했지만 과연 회사가 제대로 돌아갈 수 있을지, 그보다 내가 정신줄을 잘 붙잡고(?) 평소처럼 일을 할 수 있을지 스스로 의문스럽기도 했다. 그리고 재택 근무 2주년을 맞아 다채로웠던 2년 간의 재택 생활을 회고해보고자 한다. 통근 없는 삶 '통근'에 시달리지 않아도 된다는 것은 확실히 장점이 많았다. 출근길 2호선에서 시루떡처럼 구겨져서 30분 이상을 시달리지도 않고, 업무를 마친 뒤에는 '집에 또 언제가나'하는 걱정을..
쿼리에서 비즈니스 로직을 걷어내자
소스 코드를 보다보면 간혹 복잡하고 긴 쿼리를 맞딱뜨릴 일이 있다. 문제는 100라인이 넘어가는 긴 쿼리를 분석하고 수정해야 하는 경우다. 특히 쿼리가 어딘가 잘못되어 빠르게 고쳐야만 하는 상황이라면 눈앞이 아득하다. 아래 예시를 보자. SELECT A.ID, A.NAME, B.ADDRESS, A.NVL(GRADE, ""), CASE WHEN A.GRADE >= 4 THEN "Y" ELSE "N" END AS SCHOLARSHIP_CANDIDATE, C.PROFESSOR, A.PHONE, A.COMMENT FROM STUDENT A, CAMPUS B, PROFESSOR C, LECTURE D, MAJOR E WHERE A.PROFESSOR_ID = C.ID AND A.SCHOOL_ID = B.ID AND..