📌 서론Java의 JPA에서 복합키를 관리하는 방법에는 주로 @Embeddable, @EmbeddedId 어노테이션을 사용한다. 복합 키, 즉 복수의 필드로 구성된 기본 키를 사용하는 경우에 이러한 어노테이션을 활용하여 테이블의 기본 키를 엔티티에서 표현할 수 있다.이번 글에서는 @Embeddable과 @EmbeddedId에 대해서 알아보자 @Embeddable과 @EmbeddedId의 역할@Embeddable복합 키를 정의할 때 사용하는 어노테이션. 이 어노테이션을 사용하여 클래스를 정의하면, 해당 클래스는 다른 엔티티에서 임베디드 타입으로 사용될 수 있다. 복합 키 클래스 자체는 어떠한 생명주기도 갖지 않으며, 단지 엔티티의 일부로서 기능한다. @EmbeddedId 엔티티에서 복합 키를 사용할 때,..
Spring
HTTP 메서드 이해: 멱등성, 안전성 및 사용자 권한 검증까지 📌 서론 REST API에서 사용되는 HTTP 메서드들은 클라이언트가 서버에게 어떤 작업을 요청하는 방식을 정의한다. 이 메서드들은 특정 리소스에 대한 CRUD(Create, Read, Update, Delete) 작업을 수행하는데 사용된다. 여기에는 주로 사용되는 여섯 가지 HTTP 메서드가 있으며, 각각의 특성과 멱등성 여부, 그리고 몇몇 메서드에 대해서 사용자 권한 검증을 아래에서 설명하겠다. 멱등성(Idempotency)이란? 동일한 요청을 한 번 보내는 것과 여러 번 연속으로 보내는 것이 같은 효과를 지니고, 서버의 상태도 동일하게 남을 때, 해당 HTTP 메서드가 멱등성을 가졌다고 말한다. 다른 말로는, 멱등성 메서드에는 통계기록..
QueryDSL 사용 시 자동 업데이트 되지 않는 JPA Auditing 수정 날짜 문제 해결 방법 📌 서론 프로젝트를 개발하다가 업데이트 관련 로직은 거의 QueryDSL을 사용하고 있었다. 그러다가 updateDttm 컬럼값이 바뀌지 않는 걸 확인하고 이를 수정하려다 알게 된 사실을 정리해보려고 한다. Auditing 필드 선언 JPA와 QueryDSL을 사용하여 엔티티의 생성 날짜와 수정 날짜를 자동으로 관리하는 것은 매우 흔한 패턴이다. 다음 코드는 우리가 작성한 생성 날짜와 수정 날짜 클래스다. /** * Auditing 필드 - 생성시간 등록 * 이 필드를 상속받으면 생성시간만 auditing이 적용된다. */ @ToString @Getter @MappedSuperclass @EntityLis..
QueryDSL에서 Projections.constructor 사용해서 SQL 함수 사용하기 문제 상황 SubComment와 Recipe 엔티티에는 다음과 같이 LocalDateTime 타입으로 선언된 생성 날짜가 있다. @CreatedDate @Column(name = "create_dttm", nullable = false) private LocalDateTime createDateTime; 이렇게 선언되어 있는 생성 날짜를 각각의 DTO객체인 SubCommentListResponseDto와 RecipeListResponseDto에서 String 객체인 createDate로 맵핑해서 조회하려고 시도했다. private String createDate; QueryDSL에서는 TO_CHAR 함수를 사용하..
스칼라 서브쿼리(Scalar Subquery)에서 Limit절 오류 해결 문제 상황 레시피의 썸네일 이미지를 가져오기 위한 쿼리 작성 시 문제가 발생했다. 목표는 각 레시피별로 fileOrder가 가장 낮은, 즉 가장 먼저 업로드한 썸네일 하나만을 추출하는 것이었다. 이를 위해 JPQL을 사용하여 서브쿼리를 구성하고, orderBy와 limit(1)을 통해 단일 결과를 얻으려 했다. 하지만 예상과 달리 문제가 발생했다. // 레시피 썸네일 조회 서브쿼리 JPQLQuery recipeThumbnailSubQuery = JPAExpressions .select(recipeFileEntity.storedFilePath) .from(recipeFileEntity) .where(recipeFileEntity.re..
QueryDSL에서 NPE 해결하기 - 서브쿼리와 외부 조인의 활용 📌 서론 QueryDsl을 이용해서 쿼리문을 작성하던 중 NPE가 발생하는 이슈가 생겼다. 이유는 join의 방식에 있었는데 같이 알아보자. 문제 상황 회원 정보와 함께 프로필 이미지 경로를 조회하는 QueryDSL을 작성하는 과정에서, 특정 문제에 직면했다. 코드는 다음과 같다: jpaQueryFactory .select(Projections.fields(MyPage.class, memberEntity.id.as("memberId"), memberEntity.memberFileEntity.storedFilePath.as("profileImageFilePath"), memberEntity.nickname.as("nickname"), me..
스프링 이벤트 리스너 테스트를 위한 @SpyBean과 @MockBean의 활용 📌 서론 이전 글에서는 @SpyBean의 기본적인 개념과 역할에 대해 알아보았다. 이번 글에서는 스프링 이벤트 리스너 클래스를 테스트하는 데 @SpyBean과 @MockBean을 어떻게 활용할 수 있는지 구체적으로 살펴보자. 특히, 이벤트 리스너의 호출 여부와 반응을 확인하는 방법에 초점을 맞추어볼 것이다. 🔻 @MockBean과 @SpyBean에 대해서 잘 모른다면 아래 글을 참고하면 좋다. 🔻 @MockBean과 @Mock의 차이 (+ @InjectMocks) 스프링 테스트 코드: @MockBean과 @Mock의 차이 (+ @InjectMocks) 스프링 테스트 코드에서 @MockBean과 @Mock의 이해와 활용 📌 서론..
RequestDto에서 MultipartFile 필드 사용 방법: 객체 바인딩 방법부터 테스트 코드까지 📌 서론 기존에 RequestDto로 사용하던 dto에 MultipartFile 필드를 추가해줘야 할 일이 있었다. RequestDto에 MultipartFile 필드를 추가해 주면서 기존에 사용하던 방식과 다르게 사용해야 하는 부분들이 여러 개 있어서 그 점에 대해서 설명해보려고 한다. 특히, @RequestBody 대신 @ModelAttribute 어노테이션을 사용해야 하는 이유와 RequestDto에 Setter 메서드가 필요한 이유, 그리고 테스트 코드의 수정에 초점을 맞춰 설명하겠다. 1. 컨트롤러 어노테이션: @RequestBody에서 @ModelAttribute로 전환 기존에 컨트롤러에서 ..