Spring 14

[SpringBoot] DB 공통 데이터 초기화하는 방법

여러 개발자들 간 협업을 할 때, 공통 된 데이터(혹은 특정 데이터)가 세팅 된 상태에서 개발하기 위한 방법을 기록하고자 작성한 글입니다. 개발자라면 당연히 아는 말이겠지만, 여기서 말하는 초기화는 Reset을 의미하는 초기화가 아니라, '객체를 초기화하다.'에서 쓰이는 초기화이다. 데이터베이스에 연결하는 시점에 특정한 데이터셋을 넣는다는 것이다. 왜 DB 공통 데이터 초기화가 필요할까? 회사에서 개발하는 조각투자(토큰 증권) 관련 프로젝트에서 API를 개발하는데, 특정 API들이 동작하기 위해서 DB의 특정 데이터 들이 필요한 상황이 있었다. 예를 들어 계좌이체라는 API를 개발하기 위해서는 당연히 입, 출금 하는 사람의 계좌가 DB에 존재해야 하고, 잔액 또한 존재해야 한다. 이런 상황처럼 API가 ..

Spring 2024.06.10

[Gradle] 공통 모듈을 참조하는 FatJar 빌드하기

이 글의 목적 : 서로 다른 모듈이 공통 모듈을 참조하여 빌드하는 방법을 기억하기 위함 회사에서 업무로 기존 Maven으로 빌드하는 jar파일들을 gradle로 바꿔서, 공통모듈을 서로 다른 모듈이 참조 한 상태에서 jar파일로 빌드하라는 업무를 맡게 되었다. 아래 그림처럼 Gcomm이라는 모듈이 공통모듈이다. GSchedule이라는 모듈과 GBatch라는 모듈에서 Gcomm에서 제공하는 클래스를 참조해서 사용하고 싶은데, jar파일로 빌드를 하면 Gcomm을 참조하지 못하는 문제가 발생했다. jar파일을 빌드할때, 컴파일 시에는 클래스패스를 참조할 수 있지만 런타임(실행시점)에 클래스패스를 찾을 수 없어서 오류가 발생한 것이었다. 이에 대한 대안으로 FatJar를 사용하여 공통모듈을 함께 Jar파일로 ..

Spring 2024.05.13

Mockito를 사용한 컨트롤러 테스트에서 null이 반환될 때

이 글의 목적 : 객체의 동등성에 대해 정확하게 이해하고 실수를 반복하지 않기 위함 아래와 같이 유저 로그인 컨트롤러 테스트를 작성했다.OauthService 클래스를 MockBean으로 선언했다. 그리고 컨트롤러에서 호출하는 OauthService의 메서드를 모킹했다.그리고 호출을 한 결과 전역응답객체에서 반환하는 메타데이터 (success:true, status:200)는 정상적으로 반환되었지만, 호출된 OauthService의 메서드가 반환하는 값이 data 필드에 null로 바인딩되는 문제가 발생했다. @DisplayName("유저 로그인 컨트롤러 테스트")@WebMvcTest( controllers = {OauthController.class})@WithMockUserclass UserContr..

Spring 2024.05.06

[nGrinder] 실행 방법 및 오류 해결

컨트롤러 설치 및 실행 중 발생한 에러 깃헙에서 nGrinder War 파일을 다운로드 한 뒤 터미널에서 War파일이 있는 경로로 이동한다. java -jar ngrinder-controller-3.5.9.war --port=8300 위 명령어를 실행해서 8300번 포트로 war파일을 실행한다. 이런 에러가 뜬다. 임시파일을 지정할 경로를 명시하지 않아서 생기는 오류였다. java -Djava.io.tmpdir=/Users/cha/ngrinder -jar ngrinder-controller-3.5.9.war --port=8300 위와 같은 명령어로 tmp파일을 저장할 경로를 명시하고 다시 실행해준다. 반가운 스프링이 반겨준다. 잘 실행되나 싶었지만... 예외를 뱉어내며 서버가 죽는다 하.... 한숨이 나..

Spring 2024.03.14

[Spring Boot / gradle] Cannot load driver class: org.mariadb.jdbc.Driver 해결

갑자기 잘 되던 프로젝트를 Run 해보니 위와 같은 오류가 생겼다. 지금은 해결이 되었지만, 오류가 난 시점에는 yaml파일에 밑줄 친 부분이 빨간색으로 표시되며 에러를 발생시키고 있었다. Cannot load driver class: org.mariadb Cannot load driver class: org.jdbc Cannot load driver class: org.Driver 구글링을 해보니, Gradle 에서 해당 드라이버를 인식을 못하는 것 같다는 의견이 있었다. 위와 같이 Maven Repository에서 3.1.4라는 버전 명이 명시 된 Dependency로 build.gradle을 수정하고 Reload 하니 해결되었다. 버전을 명시해주지 않으면 최신 버전이 설치되는데, 버전이 업데이트 되..

Spring 2024.03.14

[SpringBoot] FileZilla로 AWS EC2 접속해서 배포하기

첫번째로 인텔리제이에서 Gradle에서 build에 bootJar로 빌드를 하게 되면 왼쪽에 build/libs 디렉토리안에 .SNAPSHOT.jar 파일이 생성된다. 이 jar 파일 안에는 톰캣이 내장되어 있어서 AWS ec2 인스턴스에 이 jar 파일을 넣어주면 배포가 완료된다. 여러 방법이 있지만 그 중에서도 FTP 프로토콜을 사용해서 파일을 쉽게 전송할 수 있는 FileZilla를 사용해서 배포를 진행했다. SFTP 프로토콜을 선택하고 호스트에 EC2 인스턴스의 퍼블릭 IPv4주소를 입력하고 로그온 유형은 비밀번호 묻기나, 인스턴스를 생성했을 때 생성되는 pem 파일 둘 중 하나를 선택하면 된다. 우측에 ec2 인스턴스 내에 app 내에 jar 파일을 생성하며 된다. 서버내에 jar파일을 구동시켜..

Spring 2023.12.13

[Spring] Static Method를 Mocking Test 하는 방법

1.  Mocking Test를 하는 상황 3차 토이프로젝트를 진행하고, Mockito라는 테스트 도구를 사용하여 Service 계층의 테스트를 진행했다. Mockito를 사용하면 실제 객체를 모방한, Mock 즉 가짜 객체를 생성할 수 있다. 이 가짜 객체를 생성하는 이유는 간단하다. 테스트를 띄울 때 @SpringBootTest 스프링에 등록된 빈이 다 띄워지면서 테스트가 무거워지게 되고 실제 다양한 모듈이 복잡하게 연결된 경우 테스트가 더욱 무거워지게 된다. DB와 연결하지 않고, 즉 스프링을 띄우지 않고 Mock객체의 행동을 미리 정의하여 테스트를 수행하는 것이다. 2. 문제가 되었던 상황 여행을 생성하는 서비스 계층의 로직이다. 먼저 파라미터로 tripCreateRequest를 전달받는다. 1..

Spring 2023.11.19

[JPA] fetchType.EAGER(즉시로딩)의 N+1문제의 원인과 해결방법

1. N+1 문제란? N+1 문제란 한 번의 쿼리를 날렸을 때, 원하지 않은 N개의 쿼리가 추가적으로 실행되는 현상을 뜻한다. 이 N+1문제는 JPA Repository를 사용해 조회(Read)할 때 발생한다. 그리고 1 : N, N : 1 구조에서 나타나는데, 로딩전략에 따라서 다르게 발생한다. 로딩전략이 EAGER, 즉시로딩으로 조회하는 경우 로딩전략이 LAZY, 지연로딩으로 데이터를 가져 온 이후, 연관관계인 하위 엔티티를 다시 조회하는 경우 발생한다. N+1 문제가 발생하는 이유는 JPA Repository로 find시 실행하는 첫 쿼리에서 하위 엔티티까지 한번에 가져오지 않고, 하위 엔티티를 사용할 때 추가로 조회하기 때문에 발생한다고 한다. 그리고 JPQL은 기본적으로 글로벌 Fetch전략을 ..

Spring 2023.11.09

[JPA] 즉시로딩과 지연로딩

1. 테이블 구조 현재 위와 같은 구조로 테이블이 정의되어 있다. trip과 itinerary가 1 : N 관계이다. RFP에 나와 있는 trip 조회 API의 요구사항에는 위와 같이 여행을 조회할때 여정의 이름들을 함께 보여주도록 되어 있다. 나는 조금 변형하여 특정 여행을 조회할때 여정 이름들을 함께 보여주도록 구현해보았다. 2. Service 계층 로직 로직이 수행되는 서비스 계층의 메서드이다. 동작하는 방식을 살펴보면 매개변수로 넘어온 tripId로 DB에 여행이 존재하는지를 먼저 확인한 후에, 없다면 예외를 반환한다. (RuntimeException을 던지도록 임시로 구현했다.) 그리고 여행이 존재하면 반환한 trip 엔티티 인스턴스를 DTO로 변환해야 한다. 3. FetchType.EAGER..

Spring 2023.11.08

[JPA]JPA 양방향 매핑

1. JPA에서의 양방향 매핑이란 토이 프로젝트로 진행한 '여행과 여정을 기록하는 SNS 서비스' 프로젝트를 마치고, JPA를 능숙하게 다루기 위해서 공부를 하고 있다. 혼동하기 쉬운 개념을 정리하고자 포스팅을 한다. 여행과 여정은 1 : n 관계이다. DB에서는 방향을 설정해주지 않아도 FK를 활용한 조인으로 여행 테이블에서 여정테이블을 접근할 수 있고, 여정 테이블에서 여행테이블에 접근할 수 있다. 하지만 JPA는 ORM(Object Realtionial Mapping) 즉, DB의 테이블을 객체의 클래스로 매핑한 기술이기 때문에 DB와 같은 개념으로 생각하면 안된다. JPA는 양방향 매핑이 DB처럼 양방향 관계가 설정되어 있는 것이 아니다. 아래 그림 처럼 객체의 참조를 통한 2개의 단방향 매핑을 ..

Spring 2023.10.31