java/spring
[Spring] @TransactionalEventListener에서 예외가 발생하지 않는 이슈
문제 @TransactionalEventListener에서 예외가 발생하지 않는 이슈 이게 무슨말인가 하면, @TransactionalEventListener에서 예외 발생 시, 예외를 찍어주지 않는다. 처음엔 예외 자체가 발생하지 않았다고 생각했는데, 로그를 debug로 찍어보면 잘 나온다. 즉, 예외는 발생했지만 해당 예외가 error가 아닌 debug로 찍힌다는 것. 원인 콜스택을 분석해봤다. @Transactional이 붙은 메서드를 본 메서드, @TransactionalEventListener를 이벤트 메서드라고 했을 때, 이벤트 메서드는 본 메서드의 트랜잭션이 커밋된 이후, 실행하는 메서드다. 이 때 이벤트 메서드는 실행 후 종료 직전 TransactionSynchronization.after..
[Spring] 스프링 디렉터리 패키지 구조
계층형 디렉터리 구조 com ㄴ example ㄴ nuribank ㄴ config ㄴ controller ㄴ domain ㄴ repository ㄴ service ㄴ security ㄴ exception 스프링 각 웹 계층들을 대표하는 클래스, 디렉터리들을 기반으로 패키징한다. 스프링 웹 계층 Web Layer: 사용자의 요청과 이에 대한 응답 반환의 전반적인 처리가 일어나는 영역 Service Layer: Web Layer와 Repository Layer 사이에서 실질적인 애플리케이션 비즈니스 로직이 일어나는 영역 Repository Layer: DB에 접근 및 통신하는 영역 장점 전체적인 구조를 빠르게 파악할 수 있다. 단점 각 패키지에 클래스들이 너무 많이 모이게 된다. 하나의 패키지 안에 서로 의..
[Spring] Spring Data JPA의 페이징
인자 타입 - Pageable findAll()과 같이 컬렉션 조회를 하게 되면 페이징이 필요할 때가 있다. 페이징을 위해서는 기본적으로 몇 번째 페이지인지에 대한 정보와(page) 한 페이지당 보여줄 데이터의 개수가(size) 필요하다. Spring Data JPA는 이러한 정보를 위해 Pageable 인터페이스를 사용한다. @GetMapping public ResponseEntity page(@RequestParam int page, @RequestParam int size) { Pageable pageable = PageRequest.of(page, size); Page members = memberRepository.findAll(pageable); return new ResponseEntity(..
[Spring] @ControllerAdvice, 특정 예외 발생 시 404에러가 발생하는 이슈
문제 서버에서 IllegalArgumentException 등의 여러 예외는 미리 설정한 @ControllerAdvice를 지나게 되는데, 분명 ExceptionHandler에서 특정 예외에 대해 400, 403 에러 등의 status code를 지정했지만 전부 404 에러로 바뀌어서 리턴된다. @ControllerAdvice class CherryAdminGlobalExceptionHandler { @ResponseStatus(HttpStatus.BAD_REQUEST) // -> 400코드 @ExceptionHandler(IllegalArgumentException::class) fun handle(ex: IllegalArgumentException): Response { log.error("{}", ..
[Spring] Spring AOP와 실무 응용
AOP AOP(Aspect Oriented Programming): 관점 지향 프로그래밍 관심사의 분리를 허용함으로써 모듈성을 증가시키는 것이 목적인 프로그래밍 패러다임이다. Spring AOP Spring에서도 AOP를 지원하며, 공통적으로 처리해야할 부분은 따로 모듈화해서 개발자가 비즈니스 로직에만 집중할 수 있도록 해준다. 예를 들어, 어떤 API의 어느 지점(Pointcut)에서 어떤 작업을 수행할 것인지(Advice)를 공통적으로 처리할 수 있다. 다음 예시를 보자. (본 코드는 Kotlin을 기준으로 작성되었다) Pointcut "어느 지점에서" @Aspect class PointcutList { @Pointcut("execution(* com.example.ltaop..controller....
[Spring] PostgreSQL - PostGIS, JPA를 통해 공간 데이터 다루기
데이터베이스에 숫자, 문자열이 아닌 점, 선, 면 등의 정보를 담아야 할 때, 주로 공간 데이터를 사용한다. 본 포스팅에서는 Spring + JPA 환경에서 PostgreSQL의 extension인 PostGIS를 통해 공간 데이터를 다루는 방법을 알아보겠다. PostGIS의 도입 배경과 설치 과정은 아래 글을 참고하자. 2023.01.11 - [database] - [Postgresql] PostGIS 설치 - MySQL이 아닌 PostgreSQL을 사용하는 이유 [Postgresql] PostGIS 설치 - MySQL이 아닌 PostgreSQL을 사용하는 이유 배경 프로젝트 도중 공간 데이터를 다룰 일이 있었다. 나는 주로 MySQL을 사용하기 때문에 처음에는 MySQL이 지원하는 공간 데이터 타입(..
[Spring] Mockito when으로 repository save 리턴받기
문제 단위테스트로 Mockito를 사용하던 중, repository save의 리턴 값에 대한 assert를 하고 싶었다. 그러나 객체가 실제 DB에 저장되지 않기 때문에 repository save는 null을 리턴한다. 나는 save한 객체를 그대로 받고 싶었고, 참고자료를 통해 해결했다. 해결 when(userRepository.save(any(User.class))).then(AdditionalAnswers.returnsFirstArg()); repositroy save로 어떤 User가 넘어가든, save의 첫 번째 인자를 리턴하도록 stubbing을 설정했다. 이제 리턴받은 객체로 원하는 검증을 할 수 있다. https://stackoverflow.com/questions/26161917/mo..
[Spring] AWS S3 압축 파일 풀어서 업로드하기 - TransferManager
이전에 Spring을 통해 S3 파일을 압축해서 다운로드하는 글을 작성했는데, 많은 도움이 되었다. 2022.08.05 - [java/spring] - [Spring] AWS S3 파일 압축해서 다운로드 - 여러가지 방법 비교분석 [Spring] AWS S3 파일 압축해서 다운로드 - 여러가지 방법 비교분석 이전에 Spring을 통해 S3에서 파일을 다운로드하는 API를 개발한 적이 있었다. 2021.08.05 - [java/spring] - [Spring] AWS S3에서 Spring Boot로 파일 다운로드 [Spring] AWS S3에서 Spring Boot로 파일 다운로드.. gksdudrb922.tistory.com 이번에는 반대로 압축파일을 업로드하면 S3에 풀어서 저장되는 API를 구현하고자..