TroubleShooting & Study 13

[Transactional] propagation=requires_new 옵션으로, 자식 트랜잭션의 예외에 상관없이 부모 트랜잭션 커밋하기

Untitled 서비스에서는 회원가입시 '기본 유저 정보' 외에 '반려 동물' 정보, '관심사' 정보를 입력받아서 처리해준다.회원가입을 구현하셨던, 개발을 꽤 잘하는 김 모 개발자님은(지금은 취뽀하셔서 함께 하지 못하신다.. 기쁘면서 슬프다) 회원가입 과정에서 반려동물 정보와 관심사 정보를 생성할 때 발생한 예외가 회원가입에 영향을 미쳐서 롤백된다면 유저 경험에 좋지 못하다고 생각을 하셨고, 과감하게 @Transactional을 빼버리셨다.(@Transactional에서 Exception이 발생하면 roll-back only mark가 생기고, 예외 처리를 하더라도 이 트랜잭션은 재사용이 불가능하다. 왜 그런지는 다음 링크를 참고해보자! https://techblog.woowahan.com/2606/) ..

[Github Actions] Test Code Build 실패 (Caused by: org.hibernate.HibernateException at DialectFactoryImpl)

현재 서비스는 Github Actions를 사용해서 CI/CD를 구성했다. 이전에는 테스트 코드를 작성하지 않았기에 '/gradlew build -x test'를 사용해서 테스트 없이 build를 진행하였는데, 이번에 테스트 코드를 간단하게 작성하면서 '/gradlew build'로 바꾸어서 빌드 단계에서 테스트까지 진행하도록 수정했다.  문제 발생 역시나 첫 try 한 build는 실패. infra는 한 번에 성공하면 infra가 아니지 ㅋㅋ..'java.lang.IllegalStateException at DefaultCacheAwareContextLoaderDelegate' 에러가 발생하면서 빌드에 실패했다.      원인 파악 구글링을 해본 결과 'Caused by: org.hibernate.Hi..

[Template Method, Strategy, Callback Pattern] 템플릿 메서드 패턴, 전략 패턴, 콜백 패턴

개발을 하다보면 여러 클래스에서 공통적으로 사용되는 코드와 각 클래스마다 다른 구현 사항이 섞여있는 경우를 종종 볼 수 있다. 이 경우 중복되는 코드가 발생하고, 유지∙보수가 힘들어진다. 따라서 문제점을 해결하기 위해 우리는 변하는 코드와 변하지 않는 코드를 분리 할 필요가 있다. 문제는 변하는 코드가 변하지 않는 코드 중간에 섞여있다면 단순히 메서드로 추출하는 것이 어려운 경우가 있는데, 다음의 패턴들을 통해 해결할 수 있다.      Template Method Pattern    템플릿 메서드 패턴은 공통으로 사용되는(변하지 않는) 메서드를 상위 클래스에서 구현하여 템플릿화 하고, 세부 동작은(변하는 코드) 이를 사용하는 하위 클래스에서 각각 다르게 구현하는 패턴이다   AbstractTemplat..

[Entity] Domain Entity, DB Entity, Persistence Object (feat. Hexagonal)

* 김우근 님의 'Java/Spring 테스트를 추가하고 싶은 개발자들의 오답노트' 강의를 보고 작성된 글입니다. 제 견해가 섞여 들어있기 때문에 강사님의 의견과 다를 수 있습니다.      Java + SpringBoot 개발자라면 entity라는 말을 질리도록 들어봤을 것이다. 그런데 강의에서 'Entity는 JPA랑 상관이 없다' 라고 말하길래 한번 정리를 해보고자 한다.     Entity(엔티티) 먼저 우리가 흔히 말하는 엔티티는 다음의 세 가지를 뜻한다고 볼 수 있고, 강의에서는 각 개념들을 모두 구분짓고 있다 EntityDomain Entity (도메인 엔티티)SW에서 어떤 도메인이나 문제를 해결하기 위해 만들어진 모델비즈니스 로직을 들고 있고, 식별 가능하며, 일반적으로 생명 주기를 갖는다..

[Pagination] Custom Cursor-based Pagination (정렬된 커서기반 페이지네이션)

우리는 정렬된 데이터의 수가 많을 때, offset-based pagination을 사용하기보다는 cursor-based pagination을 사용한다. 이를 통해 '데이터의 변화가 있을 때 중복 데이터 노출 문제'와 'offset으로 인한 성능 이슈'를 해결할 수 있다. 하지만 실제 프로젝트에서는 단순히 column의 id를 기준으로 정렬된(대부분 최신순이겠죠?) 데이터만을 사용하는 경우는 거의 없을 것이다.예를 들어 다음과 같은 엔티티가 있다고 가정해 보자@Entity@Getter@NoArgsConstructor(access = AccessLevel.PROTECTED)@Table(name = "product")public class Product extends BaseTimeEntity { @I..

[다형성] Interface를 통해 여러 타입 처리하기

이전글: https://kdh0518.tistory.com/entry/Reflection-%EB%A6%AC%ED%94%8C%EB%A0%89%EC%85%98-%EC%A0%9C%EB%84%A4%EB%A6%AD%EC%9C%BC%EB%A1%9C-%EC%97%AC%EB%9F%AC-%ED%83%80%EC%9E%85-%EC%B2%98%EB%A6%AC%ED%95%98%EA%B8%B0-feat-Lombok [Reflection] 리플렉션 & 제네릭으로 여러 타입 처리하기 (feat. Lombok)현재 개발 중인 서비스는 모바일 화면을 기준으로 개발하다 보니 cursor-based 무한스크롤 방식으로 조회하는 기능이 많다.cursor-based로 구현할 때 항상 마지막 cursor를 구한 후 클라이언트와 주고받kdh051..

[Reflection] 리플렉션 & 제네릭으로 여러 타입 처리하기 (feat. Lombok)

현재 개발 중인 서비스는 모바일 화면을 기준으로 개발하다 보니 cursor-based 무한스크롤 방식으로 조회하는 기능이 많다.cursor-based로 구현할 때 항상 마지막 cursor를 구한 후 클라이언트와 주고받아야 하는데, 이를 구하는 메서드는 많은 곳에서 사용된다.  예를 들어 다음 메서드를 보자위의 메서드는 List로 형식으로 된 content를 받아서 마지막 값에서 userShortsId를 추출해 낸다. 하지만 서비스에는 수많은 조회 기능이 존재하고, content에 FeedShortsOutDto가 아닌 다른 Dto가 들어오는 경우도 생기게 되었다. 물론 모든 경우마다 메서드를 만들어서 사용해도 되지만, 다른 Dto에도 공통적으로 userShortsId를 cursor로 사용하고 있었기에 중복..

[Proxy Pattern] 프록시 패턴

Proxy  영어로 Proxy는 '대리', '대리인' 이라는 뜻을 가지고 있다. 뜻 그대로 프록시 패턴이란, 원본 객체에 직접적으로 접근 하는 것이 아니라 어떤 '대리자'를 통해서 간접적으로 원본 객체를 사용하는 것을 말한다.  그림을 통해 자세히 알아보자 인터페이스를 구현한 'Origin Object'와 'Proxy Object'가 있다. 'Proxy Object'는 'Origin Object'를 컴포지션하여 멤버 변수로 사용하고있다. 이때 Client에서 요청이 온다면 다음처럼 작동 할 것이다.Client에서 Request를 보냄Controller를 거친 뒤, 'Origin Object'가 아닌 'Proxy Object'를 호출'Proxy Object'는 method A를 구현하고, 기타 작업을 수행..

[application.yml] 외부포트 / 내부포트 연결하기

** 컨테이너 실행 상태: docker run --port 외부포트:내부포트 Spring에서 application.yml 설정 'ec2 url'을 사용해서 연결하는 경우 외부포트를 사용해서 연결하는 것과 같다 == 외부포트로 연결해야한다 'container name'을 사용해서 연결하는 경우 내부포트를 사용해서 연결하는 것과 같다 == 내부포트로 연결해야한다

[VScode] 코드 스니펫 생성 방법 (커스텀 템플릿 생성, 자동완성)

Snnipet 스니펫(Snippet)은 재사용 가능한 소스 코드, 기계어, 텍스트의 작은 부분을 일컫는 프로그래밍 용어이다. 사용자가 루틴 편집 조작 중 반복 타이핑을 회피할 수 있게 도와준다. - 위키백과 간단히 말해서 템플릿이라 생각하면 된다. 예시를 보면 확실히 이해가 될 것이다 다음 알고리즘 문제 풀이들을 보자 서로 다른 알고리즘 문제를 풀고 있지만, 동일한 형태의 주석을 이용해서 메모하는 것이 보일 것이다 이처럼 주석이든 코드든 상관없이 일정한 형태의 템플릿을 자주 사용한다면, 다음처럼 코드 스니펫을 사용하여 편리하고 빠르게 반복 작업을 수행 할 수 있을 것이다 코드 스니펫 설정 방법 1. Code -> 기본 설정 -> 사용자 코드 조각 구성 2. 새 전역 코드 조각 파일 -> 이름 입력 후 생..