Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[feat] 관리자 이벤트 댓글 조회 & 삭제 (#37) #39

Merged
merged 9 commits into from
Aug 7, 2024

Conversation

blaxsior
Copy link
Collaborator

@blaxsior blaxsior commented Aug 7, 2024

#️⃣ 연관 이슈

ex) #37

📝 작업 내용

  1. 이벤트 이름 자동완성을 위한 검색 기능
  2. 이벤트 댓글 조회 기능
  3. 이벤트 댓글 페이징 기능
  4. 이벤트 댓글 삭제 기능

이슈

이전 feature을 구현할 당시에는 Spring Specification으로 동적 쿼리를 구현하기에 충분하다고 생각했습니다. 그런데, 사용하다보니 Spring Specification만으로는 DB에서 특정 열의 값만 가져오는 Projection 기능을 현재 시점에서는 구현할 수 없다는 것을 알게 되었습니다.

현재 프로젝트에서 EventMetadata은 이벤트와 관련된 메타데이터 정보를 포함하고 있습니다. 이때, 이벤트 자동완성 / 이벤트 목록 조회 시에는 이벤트 메타데이터의 일부분 데이터만 필요하므로, 모든 데이터를 fetch 하는 것은 db 측면에서 비효율적입니다. 이때 Spring Specification을 사용하는 경우 Projection을 수행하더라도 전체 데이터를 가져오는 방식으로 동작하고 있어 비효율적입니다. 관련 링크를 첨부합니다.

이슈 링크

위와 같은 문제로 인해 크게 2가지 방법을 고민하고 있습니다.

  1. queryDSL 등 동적 쿼리가 가능한 방법 도입
  2. jpa criteria query 방식과 조합, 커스텀 db 구현

전반적인 개발이 기간 내에 완료되면 이 부분을 보강해 볼 예정입니다.

검색 기능이 동일하게 사용될 여지가 있어 기존 specification을 분리.
searchOnName / searchOnEventId로 나눴지만, 내부적으로는 둘 다 eventId에 대해 동작하고 있었다. searchOnName은 name에 대해 동작하도록 수정
…할당하는 보일러 플레이트 제거(#37)

개선점: 현재 Spring Specification은 Projecton 할 때 모든 데이터를 db에서 가져온 후 처리한다. 필요한 데이터만 가져올 수 있도록 queryDSL 도입 등 고민 필요
Spring 메시지 기반으로 사용할 수 있도록 설정 조사 + 커스터마이징 필요
@blaxsior blaxsior self-assigned this Aug 7, 2024
@blaxsior blaxsior added the feat 기능 구현 label Aug 7, 2024
@win-luck win-luck self-requested a review August 7, 2024 09:18
@win-luck win-luck linked an issue Aug 7, 2024 that may be closed by this pull request
4 tasks
Copy link
Collaborator

@win-luck win-luck left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

요구사항 대비 굉장히 난해했던 구조였는데 구현해주신다고 고생많으셨습니다~!

Comment on lines +30 to +32
@Operation(summary = "관리자가 이벤트에 대한 댓글 목록 조회", description = "이벤트에 대한 댓글 목록을 조회한다.", responses = {
@ApiResponse(responseCode = "200", description = "이벤트에 대한 댓글 목록 조회 성공")
})
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ResponseCommentsDto 반환값 표기도 추후 부탁드립니다!

Comment on lines +77 to +83
public ResponseCommentsDto searchComments(String eventId, Integer page, Integer size) {
PageRequest pageInfo = PageRequest.of(page, size);

var comments = commentRepository.findAllByEventId(eventId,pageInfo)
.getContent().stream().map(ResponseCommentDto::from).toList();
return new ResponseCommentsDto(comments);
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Transcational(readOnly = true) 부탁드립니다.

@blaxsior blaxsior merged commit b945d50 into dev Aug 7, 2024
1 check passed
import org.springframework.data.jpa.domain.Specification;

public class EventSpecification {
public static Specification<EventMetadata> withSearch(String search) {
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

withSearch는 이벤트 이름 및 이벤트 id를 기반으로 검색하는 Predicate 기능을 동시에 포함했습니다. 이때, 이벤트 id 기반으로 검색하는 기능의 경우 (1)이벤트 리스트 검색, (2) 댓글 검색을 위한 이벤트 목록 검색 2가지 기능에 거의 동일한 로직으로 사용될 수 있어 둘을 분리했습니다.


Page<BriefEventDto> eventPage = emRepository.findBy(
searchOnName.or(searchOnEventId),
(p) -> p.as(BriefEventDto.class)
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Spring Specification의 findBy 메서드에서는 2번째 인자로 projection을 지정할 수 있습니다. 이때 (1) .as의 파라미터로는 인터페이스 타입만 지원하고, (2) 현재 searchEvents 메서드는 응답 상황에만 사용되어 dto를 직접 만들어야 하는 경우가 없으므로 기존 EventMetadata 객체를 Dto로 변경하는 보일러 플레이트를 걷어내 간결하게 만들었습니다.

hibernate 쿼리를 분석해 본 결과 findBy에 의한 projection은 db에서 모든 열의 데이터를 가져오는 over fetch가 발생합니다. 추후 이 부분을 queryDSL 또는 custom repository 또는 유틸 기능을 만들어서 개선해보고자 합니다.

briefEventDto.eventType = eventType;
return briefEventDto;
}
EventType getEventType();
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Spring Specification에서 projection 용도로 사용할 수 있도록 클래스 기반 dto에서 interface 기반으로 변경했습니다. 전반적인 코드가 좀 더 깔끔해진 것 같습니다. swagger은 getter위의 주석을 인식하는 것을 확인했습니다.

@@ -32,6 +32,10 @@ public class DrawEvent {
fetch = FetchType.EAGER) // 추첨 이벤트는 항상 metadata와 함께 사용되므로 EAGER로 설정
private List<DrawEventMetadata> metadataList = new ArrayList<>();

@OneToMany(mappedBy ="drawEvent")
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

사용자 참여 여부 정보에 대한 OneToMany가 등록되어 있지 않아서 등록했습니다.

@win-luck win-luck deleted the feature/37-admin-comment-act branch August 13, 2024 03:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feat 기능 구현
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[feat] 관리자 이벤트 댓글 조회 & 삭제 (#37)
2 participants