[Mybatis] 로컬 캐시 문제: 프로시저 호출 시 발생하는 캐시 이슈
·
Spring
서론진행 중인 프로젝트에서 `sequence` 테이블을 별도로 두고 프로시저를 통해 PK를 채번하는 시스템에서 예상치 못한 캐시 문제를 마주했던 내용을 정리했다. Mybatis 로컬 캐시는 기본적으로 활성화되어 있는데, 이게 별도 트랜잭션에서 실행되는 프로시저와 만나면서 예상치 못한 동작을 하는 바람에 원인을 찾기까지 꽤 많은 삽질을 했다. 특히 이 프로젝트는 Mybatis 캐시 정책에 대한 제대로 된 이해 없이 "JPA와 비슷하겠지"라는 안일한 생각으로 임했던 것이 화근이었다. 하지만 막상 파보니 JPA의 영속성 컨텍스트와는 완전히 다른 캐시 정책을 가지고 있어서 더욱 혼란스러웠고, 결국 근본적인 차이점부터 다시 공부해야 했다. 실제 발생한 문제 상황프로시저를 통해 채번한 `sequence` 값이 캐시..
[Mybatis] Generic 기반 TypeHandler를 자동 등록하기
·
Spring
서론Java Enum 타입과 RDB의 enum 데이터 타입여러 프로젝트에서 `Y`, `N` 같이 특정 값들을 가지면서 해당 그룹이 잘 변하지 않으면 Enum 타입으로 설계하곤 한다. RDB에 이런 Enum 성격을 갖는 값들을 저장할 땐 데이터 타입을 `char`, `varchar`, `enum`을 사용한다. (MySQL, MariaDB, PostgreSQL 등)Mybatis EnumTypeHandlerMyBatis에선 Java의 Enum 타입을 멤버 변수 이름 그대로 매핑해 주는 `EnumTypeHandler`를 기본 TypeHandler로 사용하는데, 모종의 이유(레거시 프로젝트 등)로 DB에는 소문자나, 다른 값으로 저장해야 할 때가 있다. 이때 Java Enum 타입의 멤버 변수는 상수이기 때문에 ..
Spring Event Deep Dive
·
Spring
Spring EventSpring Framework에서 제공하는 이벤트(Event) 객체가 있습니다.이 객체는 `ApplicationContext`가 제공하는 기능의 일부인데요, Spring에 내장된 이벤트들을 이용해 특정 상황에서 원하는 동작을 수행하도록 개발할 수 있는 기능입니다.Spring Event 동작 원리동작 과정이벤트는 하나의 쓰레드에서 동작합니다. 즉, 동기적으로 동작합니다.한 쓰레드 내부에서 발행자가 이벤트를 발행(publish)하면 수신자가 이벤트를 수신(listen)하여 이벤트를 처리합니다.이벤트 발행자(Event Publisher)a. ApplicationEventPublisher 에서 이벤트를 발행한다.실제로 이벤트를 발행하는 코드를 작성할 땐 `ApplicationEventPub..
[Spring] MockMvc 사용 시 Page 인터페이스의 직렬화 문제
·
Spring
환경Spring Boot 3.3.4Amazon Corretto 17.0.11문제 발생@BeforeEachvoid setUp() { mockMvc = MockMvcBuilders.standaloneSetup(replyController) .setCustomArgumentResolvers(new PageableHandlerMethodArgumentResolver()) .build(); // 생략 ..}@DisplayName("published 값에 따른 편지와 1:1로 대응하는 답장을 페이징으로 응답할 수 있다")@ParameterizedTest@ValueSource(booleans = {true, false})void success_p..
[Spring] 회원탈퇴 시 Kakao OAuth2 연결끊기: REST API로 연결끊기 (OpenFeign)
·
Spring
이 포스팅은 회원탈퇴 로직을 구현할 때 kakao REST API 로 `연결 끊기`를 Spring 프로젝트에서 적용하는 방법에 대한 글입니다.kakao rest api 공식 문서 바로가기 Kakao Developers카카오 API를 활용하여 다양한 어플리케이션을 개발해보세요. 카카오 로그인, 메시지 보내기, 친구 API, 인공지능 API 등을 제공합니다.developers.kakao.com 공식 문서에 따르면 REST API로 `연결 끊기`를 하려면 카카오 인증 서버(https://kapi.kakao.com/v1/user/unlink)에 요청을 보내야 합니다.요청과 응답 예시는 공식 문서에서 가져왔습니다. 사용자 로그인 시 액세스 토큰을 세션이나 RDB, Memory DB 등에 저장할 수 있지만, 서비스..
[Spring] 직렬화/역직렬화 시 'is' prefix 가 안붙는 이유
·
Spring
분명 DTO 에 'is'가 있거든요유저의 정보 변경 `DTO` 에 `boolean` 타입의 필드들이 있습니다.Lombok의 `@Getter`도 붙여줬기 때문에 이 DTO가 직렬화되면 JSON 필드 이름은 `isAgreeToTerms` 같이 될 것이라고 예상했습니다.직렬화는 됐는데 'is'가 없어요직렬화된 JSON 필드를 `swagger ui`를 통해 확인해 보겠습니다. 확인해 보니, `is` prefix 가 제외돼서 직렬화된 것을 확인할 수 있었습니다.예상과 다른 필드 이름은 백엔드와 프론트엔드의 데이터 교환에서 장애를 발생시킵니다.프론트엔드 개발자는 `swagger`에 있는 대로 필드 이름을 사용하기 때문입니다. 위의 예시 코드에선 `boolean` 타입이 문제가 될 수 있습니다.`is`가 없는 JSO..
[Spring Batch] ItemWriter 가 List<T> 를 전달받으려면? (Spring Batch 5)
·
Spring
스프링 배치를 사용하다보면 ItemWriter 에 List 같은 Collection 을 전달할 때가 있습니다.저는 테스트를 위해 숙소 예약건 생성을 배치로 처리하는 과정에서 필요했었는데요, 이 과정에서 만난 문제와 해결 방법을 기록하기 위해 글을 작성했습니다.마주친 문제 : ItemWriter 는 이미 Chunk 으로 받는다설명은 Spring Batch 5 에서 구현체 JdbcBatchItemWriter 기준으로 설명합니다.해당 구현체의 `writer()` 메서드는 아래와 같습니다.구현체 JdbcBatchItemWriter 의 write() 메서드 살펴보기public void write(final Chunk chunk) throws Exception { if (!chunk.isEmpty())..
[Spring] Response DTO 직렬화 문제
·
Spring
문제Lombok을 사용하는 프로젝트에서 발생한 문제.Presentation 레이어에 응답하는 Response DTO에 @Getter를 붙이지 않았더니 JSON으로 반환되지 않는다.@NoArgsConstructorpublic class ResponseDTO { private Sting data;} 원인이는 JSON 으로 직렬화해주는 라이브러리에서 객체에 필드에 접근하기 위해 Getter 메서드들을 사용하지만, Getter가 없으면 해당 필드에 접근할 방법이 없게되고 직렬화 과정에서 제외된다.해결 방법해결 방법은 클래스 레벨에 @Getter 를 추가해주거나, 필드에 직접 @JsonProperty 를 사용해서 Getter가 없는 필드도 직렬화할 수 있도록 한다.방법1.@Getter@NoArgsConstr..