결론부터 말하자면 Spring Data Jpa의 JpaRepository를 사용할 때 발생하는 문제다. 처음 만난 문제는 PK 값을 가지고 있는 객체가 데이터베이스에는 존재하지 않을 때, 이 객체와 연관관계를 맺고 save 메서드로 영속화를 시도하면 연관관계를 맺고 있는 객체가 데이터베이스에 존재하지 않기 때문에 EntityNotFoundException이 발생한다. 두 번째 문제는 PK 값을 가지고 있는 객체를 JpaRepository.save 메서드로 영속화 했을 때, 이 객체는 영속화가 되지 않기 때문에 발생하는 문제다. 문제 코드 테스트 코드용 더미 데이터를 생성하는 클래스를 아래와 같이 만들었다. public class TestDataFactory { public static Long userI..
Tool/Spring
조회 API에 여러 개의 동적 정렬 조건과 페이지네이션 기능이 필요할 때 Spring Data JPA로 쉽게 구현할 수 있다. 이건 단순히 게시글 목록을 조회하는 상황인데, 만약 더 복잡한 연관관계의 조회라면 이 방법은 좋지 않을 수 있으니 성능을 고려하자. Controller 페이지네이션과 동적 정렬 조건을 쿼리 스트링으로 입력받는다. 정렬 조건은 sort=key,option 형식으로 입력 받는다고 설정했다. 예를 들면 /posts&sorts=createdAt,desc 같은 형식이다. @GetMapping public ResponseEntity findAll( @RequestParam(defaultValue = "0", required = false) int page, @RequestParam(defa..
회원가입 기능을 만들 때, 시간 제한이 있는 이메일 인증을 통과하도록 만들어보자. Redis를 사용하면 TTL(Time To Live)을 써서 시간 제한을 쉽게 구현할 수 있다. 로컬에 Redis 설치하기 homebrew로 간단하게 설치했다. 설치가 끝났다면 redis 서버를 실행시키자. 서버가 실행중이라면 redis-cli ping 명령어를 입력하면 PONG이라고 응답한다. brew install redis brew services start redis redis-cli ping # PONG Spring boot 의존성 및 설정 추가하기 build.gradle의 dependencies에 redis를 추가하고, application.yml에 호스트와 포트 설정을 추가하자. // Redis 의존성 추가 i..
Bean validation에서 기본적으로 제공하는 기능 이상으로 유효성 검증을 해야한다면 커스텀 어노테이션을 만들어서 검증할 수 있다. 커스텀 어노테이션 이외에 검증하는 방법은 여러가지가 있지만, 나는 컨트롤러나 서비스 레이어에서 검증 메서드를 계속 호출하는 것이 메서드의 핵심 코드를 읽기 불편하게 만든다고 생각하기 때문에 DTO의 검증은 DTO 레이어에서 처리하는게 좋다고 생각했다. 나와 비슷한 생각이신 분들을 위해 커스텀 어노테이션과 검증 클래스로 분리해서 DTO 유효성을 검사한 방법을 공유한다. 회원가입 DTO 코드 @NoArgsConstructor @AllArgsConstructor @Getter @ValidSignUpRequest // Dto에 대한 검증은 Dto에서 처리하자 public cl..
멀티미디어 파일을 포함한 글 작성 요청을 처리하는 서버를 개발할 때, 파일 저장소로 AWS S3를 사용하고 있다고 가정하자. 만약 글 작성 요청을 처리하는 중에 서버에 장애가 발생하여 요청이 중단될 경우, 트랜잭션이 실행 결과를 롤백할 때 외부 서비스인 S3의 작업은 함께 롤백되지 않는다. 그렇다면 어떻게 S3의 작업을 롤백해야 할까? 고민하고 검색해서 여러 가지 방법을 찾아봤다. 내가 작성한 메서드의 초기 형태는 아래와 같은 형식이다. S3에 이미지 파일을 올리는게 비즈니스 로직 사이에 있다. @Transactional public PostResponseDto createPost( MultipartFile[] images ) { // 불필요한 코드 지움 Post savedPost = postReposi..
service layer의 테스트 코드에 이어서 controller layer의 테스트 코드 작성하는 방법을 정리해두자. controller를 테스트하기 위해서 주로 @WebMvcTest 애너테이션(이름대로 WebMvc와 관련된 Bean이 등록된다)을 적용한 테스트 클래스에서 테스트 한다. MockMvc: 요청과 응답을 모방하는 클래스다. DispatcherServlet에 요청을 보내는 식으로 작동한다. 배운 것과 나의 생각 Spring security를 사용할 때, 유저 인증 정보를 단위 테스트에서 받을 수 없다. @WebMvcTest는 Spring security configuration을 등록하지 않기 때문에 내가 SecurityConfig에 등록한 필터가 적용되지 않는다. 그래서 SecurityC..