Back-End
-
엔티티의 1:N 관계에서의 QueryDsl fetch Join - (1) 페이지네이션Back-End/Querydsl 2022. 12. 21. 19:32
QueryDsl은 쿼리 빌더 프레임워크로써, 동적 쿼리 작성과 컴파일 시점에서의 쿼리 오류 검출이라는 큰 장점을 가지고 있다. (동적 쿼리 예시 및 QueryDsl로의 해결법 : https://jaehoney.tistory.com/185 ) 그래서 Spring Data JPA를 사용하는 개발자라면 굉장히 유용하게 사용할 수 있는 프레임워크이다. 사내카페의 포스기 백엔드 서버를 개발하던 중이었다. 팀 동료의 사정으로 팀 동료의 파트를 대신 개발을 하게 되었는데, 포스기에서 판매하는 상품을 조회하는 과정에서 쿼리가 수 십 방이 나가고 있었다. 이유인 즉슨, 테이블의 구조가 다음과 같았는데, 상품과 상품 이미지는 1:N, 상품 이미지와 이미지는 1:1의 구조를 갖고 있었다. 그리고 메뉴를 조회하는 API에 대..
-
Spring Rest docs를 활용한 API 명세를 openapi3를 활용하여 swagger로 변환하기Back-End/Spring 2022. 12. 13. 17:21
최근 사내 카페 pos기 프로젝트에서 프로젝트의 API 명세를 어떠한 방법으로 사용 할 지를 팀원들과 고민하였고, Spring Rest Docs를 사용하되 해당 정보를 openapi3를 활용하여 swagger로 띄우는 방법을 사용하기로 했다. swagger보다 초기 설정이 어렵지만, 테스트코드를 강제할 수 있고 자동으로 API명세를 작성해주는 편리함이 있어서 사용을 한다. openapi란, Restful한 API 디자인 정의의 표준이다. 즉, Api 스펙을 json 혹은 yml 형식으로 표현한 것이라고 이해하면 된다. 참고로, swagger는 openapi의 실제 실행 툴이라고 생각하면 된다. 먼저, Spring Rest Docs 사용을 위한 설정을 진행한다. // build.gradle plugins ..
-
JPA의 연관관계에 대한 고찰Back-End/JPA 2022. 11. 18. 13:58
JPA의 XtoOne 관계를 설정할 때, fetchType 옵션은 기본적으로 eager로 설정되어있다. 따라서, 따로 Lazy 타입으로 설정을 하지 않는 경우 자신과 연관관계가 있는 엔티티를 호출하는 쿼리가 자동으로 나가게 되고 성능상으로 굉장한 손해가 온다(고 한다). 이론상으로만 배워왔기에 매번 헷갈리는 경우가 많았고, 따라서 한 번 실습을 진행 해 보면서 실제로 쿼리가 동작하는 것을 관찰 해 보려고 한다. 또한, eager로 fetch된 엔티티와 연관관계가 있는 또 다른 entity가 있고, 이들 또한 eager로 설정이 되어있다면 어떻게 query가 나가게 되는지를 관찰 해 보려 한다. 먼저, 예시 Entity를 만들기 위해, 다음과 같이 Entity 관계를 설정하였다. 만들고 나니 굉장히 이진트..
-
Spring Security cors 이슈Back-End/Spring 2022. 10. 21. 13:47
사내 오픈마켓 프로젝트를 진행하던 때였다. 나는 인증/인가를 담당하고 있었던 상황이었다 기능 구현을 마치고 프론트 개발자분들과 협업을 진행하던 중, CORS 이슈가 터지고 말았다. GET Method 이외의 HTTP 메서드 요청을 보낼 때 프론트측에서 CORS 오류 메세지를 수신한다는 것을 들었고, 내가 백엔드 서버의 인증/인가 담당을 하고 있었기에(생각해 보니 상관은 없지만) 해결을 시도하였다. 시도한 방안 1. Spring Security filter에 cors 커스텀 설정 적용하기 기존에는 security 필터 체인을 사용 할 때, WebSecurityConfigurerAdapter 추상클래스를 상속받아 구현을 하였는데, 최근에는 deprecated되어 새로운 방법을 적용하는 것을 권장받는다. @B..
-
JPA Auditing과 MappedSuperClass 활용Back-End/JPA 2022. 9. 14. 15:03
프로젝트에서 리뷰, 리뷰 답변 등의 Entity를 설계할 때 생성일자와 수정일자 등의 필드가 공통적으로 들어가게 되었다. 또한 이러한 값들의 경우 매번 insert 및 update 시 값을 설정 해 주어야 한다. 이 때, JPA의 Auditing 기능과 MappedSuperClass 기능을 활용하면 이를 간단히 해결할 수 있다. 공식문서를 보면, JPA Auditing은 다음과 같이 정의되어 있다. In the context of ORM, database auditing means tracking and logging events related to persistent entities 현재 프로젝트에서는 생성 시간과 수정 시간만이 필요하므로 이를 Spring JPA Data의 @CreatedAt, @La..
-
MapStruct 라이브러리 사용법Back-End/Spring 2022. 8. 29. 12:59
Mastruct 라이브러리는 entityToDto 작업을 편리하게 진행 해 준다. DI 프레임워크를 사용하지 않는 경우에도 사용할 수 있으며, Spring과 같은 DI 프레임워크를 사용하면, 인터페이스만 정의 해 두면 빌드시점에 구현체를 만들어 준다. 해당 구현체는 인터페이스에 정의해 둔 정보를 기반으로 매핑 메서드들이 생성된다. 다음과 같이 매퍼를 작성 해 두면, 빌드 폴더에 구현체가 생성이 된다. 1. 특정 Entity를 받아서 특정 Dto로 변환하고자 할 때 => 가장 기본적인 사용 용도이며, 위 그림에서 아래 2개의 메서드처럼 사용하면 된다. 2. 특정 Entity List를 받아서 특정 Dto List로 변환하고자 할 때 => 첫 번째 메서드 정의와 같다. 자체적으로 Entity to Dto 메..
-
JPA에서, Many To One 관계의 Post 요청에서 주의할 점Back-End/JPA 2022. 8. 25. 11:27
Review 테이블이 있고, 리뷰와 함께 보여질 리뷰이미지를 의미하는 ReviewImage 테이블이 있다고 하자. 하나의 리뷰에 여러 개의 이미지를 달 수 있으므로, 이들은 1 대 다 관계이다. 리뷰를 post하는 서비스의 RequestDto는 다음과 같다. { "title" : "맛있어요", "content" : "또 가고 싶습니다.", "reviewImages" : [{ "url" : "https://naver.com" }] } postReview 서비스는 다음과 같다. @Transactional public UUID postReview(CreateReviewRequestDto dto){ Review review = Review.ReviewBuilder() .title(dto.getTitle()) ...
-
JPA의 entity update는 어떻게 이루어질까?Back-End/JPA 2022. 5. 3. 10:04
spring-data-JPA에서, entity에 대해 save 메서드는 있지만 update에 대한 메서드가 따로 없다. 이유는 JPA는 '변경감지'라는 기능을 활용하기 때문이다. 엔티티를 영속 상태로 만들 때, 처음 엔티티의 정보에 대한 스냅샷을 저장을 해 둔다. 이 후, 트랜잭션이 끝날때 까지 해당 정보를 유지하다가, 트랜잭션이 종료될 때(혹은 flush를 날릴 때) 해당 엔티티의 변화를 스냅샷과 비교한 뒤 이를 감지하여 update 쿼리를 자동으로 생성하여 DB에 날리게 된다. @Transactional public void update(Long id, String name){ Member member = memberRepository.findById(id); member.setName(name); ..