2회차

CJY·2023년 5월 11일
0

프로젝트1

목록 보기
2/8

문제 발견

JPA 엔티티를 정의할 때 id에 @GeneratedValue를 사용하면 default 전략으로 GenerationType.AUTO를 사용한다. 이 AUTO는 IDENTITY를 기본으로 사용한다고 알고 있었지만 실제 스프링이 정의하는 DDL을 살펴보면 id값 속성에 auto_increment가 없는 것을 알 수 있다.

그리고 DDL 바로 밑에 다음과 같은 테이블을 생성한다.

실제로는 테이블 시퀀스 전략을 사용한 것이다.

테이블 시퀀스

테이블 시퀀스 전략은 이름 그대로 테이블에 시퀀스 하나를 두고 새로운 id가 필요할 때마다 값을 올리면서 할당하는 것이다.

별 문제 없는 것 같은데 ?

문제는 엔티티가 여러개일 때 엔티티마다 id값이 오르는 것이 아니라 공유하는 시퀀스로 값이 오른다. 지금 나는 Board라는 엔티티 하나만 정의했지만 만약 Member라는 엔티티를 하나 더 만들고 각자 하나씩 생성하고 저장하면 각자 id값이 1이 아니라 먼저 저장한 인스턴스가 1 그 다음 인스턴스가 2로 저장된다.

즉, 통합적으로 관리하기 때문에 엔티티 별로 id값이 나누어지지 않고 합쳐서 올라간다.

해결 방법

간단하다. 전략을 IDENTITY로 바꾸면 된다.

만약 엔티티마다 설정하기 귀찮다면

다음과 같이 application.yml파일 혹은 application.properties파일에 spring.jpa.hibernate.use-new-id-generator-mappings: false를 넣어주자. 그럼 default값으로 AUTO를 사용해도 IDENTITY 전략을 사용하게 된다.

이유

hibernate 5가 AUTO의 전략을 TABLE 전략으로 새롭게 변경했다. 그리고 스프링 부트가 이 전략을 따르는 쪽을 선택했기 때문에 application.yml파일에서 따로 설정하지 않는다면 default는 TABLE 전략이 된다.

api json에 한글 깨짐

postman을 이용해 REST api 시험을 해보는 과정에서 한글 출력이 깨지는 현상이 있었다. 인텔리제이 properties파일이나 yml파일이 UTF-8 이 아니라 생기는 오류였다.

참고
https://velog.io/@shawnhansh/intelliJ-properties-%ED%8C%8C%EC%9D%BC-UTF-8-%EC%9D%B8%EC%BD%94%EB%94%A9

원드라이브 조직 동기화 파일명 변경

clean - build를 하는 과정에서 인텔리제이에서 컴파일 오류를 띄웠다. 사실 어플리케이션을 실행하는데 문제는 없지만 거슬려서 해결했다.

  1. settings - gradle - Run test using을 gradle에서 Intellij IDEA로 변경

윈도우에서 settings의 단축키는 ctrl+alt+s다.

이전에도 같은 문제가 발생해서 1번으로 해결했다.
하지만 이번에는 1번으로 해결이 안됐고 왠지 OneDrive 이름 때문에 문제가 있는 것 같았다.
OneDrive를 학교를 통해 사용하고 있었기 때문에 OneDrive - 학교이름과 같이 한글이 들어가서 문제가 있는 것 같아 강제로 바꿔봤고 문제가 해결됐다.

  1. 원드라이브 조직 동기화 파일명 강제로 바꾸기

참고로 이 방법은 50프로 확률로 성공할 수도 있고 반대로 50프로 확률로 실패할 수 있다.

윈도우 + r을 눌러 실행 프롬프트에 다음 내용을 적는다.

%LOCALAPPDATA%\Microsoft\OneDrive\settings\Business1

OneDrive를 사용하는 조직이 여러개라면 Business2, Business3, ... 이런식으로 늘어나니 이 부분은 스스로 찾아야 한다.

저 파일에 들어갔으면 uuid처럼 생긴 파일 중에 ini확장자를 가진 파일을 찾아야 한다.

그 파일을 메모장으로 열고 쭉 보면 경로가 적힌 부분이 있다. 거기서 OneDrive - 조직이름을 원하는 이름으로 바꾸고 그 이름으로 해당 경로에 파일을 하나 만들어야 한다. 그리고 컴퓨터 재부팅하면서 기도해야한다.

재부팅했을 때 다시시도 오류가 나오면 성공이다. 다시시도를 누르면 변경 끝이다.

계층형 디렉터리 구조와 도메인형 디렉터리 구조

지금까지 Controller - Service - Repository, Domain 이런 식으로 패키지 구조를 만들었다. 하지만 다양한 도메인이 생기는 프로젝트라면 도메인형 디렉터리 구조를 사용하면 더 좋을 것 같다는 생각이 들었다. 이번 프로젝트는 아직 규모가 크지 않기 때문에 적용하지 않았지만, 앞으로 프로젝트가 커진다면 도입해볼 생각이다.

ControllerAdvice

예외 처리로 ControllerAdvice를 사용하고 있다.

검증 예외를 처리하기 위해 Controller에서 BindingResult를 사용하면 하나의 메서드에서 예외도 처리하고 컨트롤러 역할도 하게 된다. 따라서 과감하게 Controller에서 BindingResult를 없애고 검증 오류로 인해 RuntimeException이 터지면 그 에러를 잡아서 응답하는 형식을 채택하여 사용 중이다.

  1. BindException.class
    @ModelAttribute 파라미터 검증 시 터지는 예외
  2. MethodArgumentNotValidException
    @RequestBody 파라미터 검증 시 터지는 예외

MethodArgumentNotValidExceptionBindingException을 상속받고 있다.

참고
https://devfunny.tistory.com/428

Api 문서화, swagger와 spring doc 사용(spring fox,Spring boot 2.x 결합 시 문제 발생)
https://hogwart-scholars.tistory.com/entry/Spring-Boot-SpringDoc%EA%B3%BC-Swagger%EB%A5%BC-%EC%9D%B4%EC%9A%A9%ED%95%B4-API-%EB%AC%B8%EC%84%9C%ED%99%94-%EC%9E%90%EB%8F%99%ED%99%94%ED%95%98%EA%B8%B0

API 문서화

진행과정 중 path variable을 사용하는 operation들에 문제가 있다. postman으로 테스트할 때는 문제가 없지만, swagger의 try it out 기능을 사용하면 internal server error, 500 에러가 발생한다.

profile
열심히 성장 중인 백엔드

0개의 댓글