IT/개발로그
[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 예외가 발생한다. 위 예제야 뻔히 보이지만 수천, 수만건의 데이터 중 단 하나의 중복이 있었다면 사전에 발견하지 못했을 것이다. 비즈니스적으로는 중복이 없어야 맞는 것이라도, 예상할 수 없었던 예외 케이스가 늘 발..
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..
[Java] Jackson 사용시 Getter를 주의하자
짧고 담백하게 결론부터 말하자면 자바에서 Jackson 라이브러리를 사용하여 json 문자열로 Serialize 할때는 getter를 주의해야한다. 예를 들어 아래와 같은 클래스가 있다고 하자. @Builder @NoArgsConstructor @AllArgsConstructor @Getter public class Product { private long id; private String name; private long price; public String getProductInfo(){ return name + price; } } 멤버 변수로 정의한 것은 id, name, price이고 편의상 getProductInfo()라는 메서드를 만들어 상품의 이름과 가격을 함께 리턴하도록 했다. 이 상태로 ..
단위 테스트는 왜 해야할까
회사를 옮기고 나서 처음 놀랐던 순간은 테스트 코드를 봤을때였다. 복잡한 비즈니스 로직을 다루면서도 테스트 디렉터리가 말끔히 비워져 있었다. 코드 레벨의 자동화된 단위 테스트보다는 e2e 테스트에 의존하고 있었으며 그래서 초래되는 문제도 적지 않아 보였다. 당연하게도(?) 팀원들은 테스트 코드의 필요성에 대해서 깊이 공감하지는 못하고 있었다. 우선 그들을 설득할 필요가 있어보였는데, 만약 누군가 나에게 왜 꼭 단위 테스트를 해야하는지를 묻는다면 뭐라고 대답할지를 생각해보았다. 내가 그동안 느낀바로는 다음과 같은 이유들이 있다. 개발자 버전의 요구사항 문서 테스트 코드를 작성하면 서비스가 충족해야하는 요구사항을 명문화해 볼수 있다. 개발자라면 요구 사항을 잘못 이해하여 일어난 대참사를 직간접적으로 경험해본..
스프링 배치 대용량데이터 처리 성능 개선기 [1편]
요구사항 혜택 고객 선정 모델을 통해 혜택 대상 고객들을 선정하고, 해당 고객들에게 쿠폰을 발급해주는 시스템을 구축해야 했다. 여기서 나는 일배치를 통해 집계된 대상 고객들에게 쿠폰을 발급하는 시스템을 설계하고 개발하기로 했다. 그런데 문제는 일별로 발급대상 데이터의 건수가 수십-수백만까지 예상되며 이를 3시간 내에 처리해야한다는 것이었다. 알던 이전에 구축해놓은 스프링 배치 서버가 있어 이를 활용해보기로 했고 전반적인 시스템 구조부터 그려봤다. Overall System Architecture 스프링 배치 관리/모니터링 도구로는 젠킨스를 활용하고 있다. 배치가 실행되면 대상고객이 집계되어있는 DB에서 타겟을 가져와서 쿠폰발급 서버에 1건 단위로 발급을 요청한다 발급 결과(쿠폰번호)를 받으면 데이터 집계..