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

[BE] feat: 하이라이트 추가 및 수정 API 구현 #813

Merged
merged 39 commits into from
Oct 11, 2024
Merged
Show file tree
Hide file tree
Changes from 36 commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
c62884c
feat: 하이라이트 기능을 위한 도메인, 테이블, 레포지토리 생성
skylar1220 Oct 9, 2024
5979829
refactor: reviewRequestCode도 서비스에 함께 넘기도록 수정
skylar1220 Oct 9, 2024
fa5aa38
feat: 하이라이트 수정을 위한 삭제, 저장 로직 구현
skylar1220 Oct 9, 2024
b55df2f
feat: 하이라이트 수정을 위한 검증 로직 구현
skylar1220 Oct 10, 2024
cbbc950
db: 하이라이트 조회 성능과 동시성을 위한 복합 인덱스 추가
skylar1220 Oct 10, 2024
84898cf
fix: 리뷰 그룹으로 질문 검증하는 로직 수정
skylar1220 Oct 10, 2024
2b74e5e
refactor: 레포지토리에 기존에 있던 메서드 활용하도록 수정
skylar1220 Oct 10, 2024
eb1459e
fix: 테이블명 오류 수정
skylar1220 Oct 10, 2024
f4418cc
refactor: 초기화시 필드 순서 수정
skylar1220 Oct 10, 2024
921cc6e
test: 하이라이트 레포지토리 테스트 추가
skylar1220 Oct 10, 2024
b3a58c3
test: 하이라이트 입력 검증 테스트 추가
skylar1220 Oct 10, 2024
a88d090
test: 하이라이트 수정 기능 서비스 테스트 추가
skylar1220 Oct 10, 2024
b8ce456
refactor: 생성자 파라미터 및 필드 순서 변경
skylar1220 Oct 10, 2024
ad59c37
fix: not null 설정 오타 수정
skylar1220 Oct 10, 2024
f87efad
refactor: 검증 순서 변경
skylar1220 Oct 10, 2024
d3abfd3
refactor: jpa 기본 메서드로 쿼리 여러개 나가는 부분을 @Query로 변경
skylar1220 Oct 10, 2024
95cf051
style: 개행 수정
skylar1220 Oct 10, 2024
bb9ebb1
refactor: 에러 메세지 수정
skylar1220 Oct 10, 2024
c700e45
db: 하이라이트 인덱스 관련 데이터 타입 int로 수정
skylar1220 Oct 10, 2024
834d900
refactor: 하이라이트 표시 위치 관련 속성을 객체로 분리
skylar1220 Oct 10, 2024
16f5d34
refactor: JPQL로 변경
skylar1220 Oct 10, 2024
f71d9de
refactor: 기존 레포지토리 메서드를 사용하도록 변경
skylar1220 Oct 10, 2024
4b28bd4
refactor: 메서드 네이밍 수정
skylar1220 Oct 10, 2024
cd6a16c
refactor: 하이라이트 위치 속성 객체에 추가 설정
skylar1220 Oct 10, 2024
fbd8fc4
refactor: 하이라이트 엔티티에서 reviewGroupId, questionId 필드 제거
skylar1220 Oct 10, 2024
1ce93e6
refactor: 기존 하이라이트 제거를 answerId를 통해 하도록 변경
skylar1220 Oct 10, 2024
ba72762
test: 책임을 이동한 테스트 제거 및 테스트 오류 수정
skylar1220 Oct 10, 2024
1c16507
db: 테이블에 questionId, review_group_id 컬럼 제거 반영
skylar1220 Oct 10, 2024
a7f25b8
refactor: 기존 중복 요청 메서드 제거
skylar1220 Oct 10, 2024
52c350b
refactor: 중복 요청의 경우 하나만 저장하도록 EqualsAndHashCode 재정의
skylar1220 Oct 10, 2024
7e546aa
refactor: 하이라이트 저장시 순서 보장 적용
skylar1220 Oct 10, 2024
55895db
refactor: HighlightPosition 검증, 객체 생성 후 하이라이트 객체 생성하도록 변경
skylar1220 Oct 10, 2024
aaf1c6c
refactor: 엔티티의 equals 조건 id로 복원 및 중복 제거 로직 삭제
skylar1220 Oct 11, 2024
560faec
refactor: HighlightPosition 객체 생성 위치 생성자 내로 이동
skylar1220 Oct 11, 2024
a3a968f
refactor: 예외명 수정
skylar1220 Oct 11, 2024
c226e21
refactor: 하이라이트 인덱스의 검증 추가
skylar1220 Oct 11, 2024
132ff57
refactor: 양수 검증 메서드명 수정
skylar1220 Oct 11, 2024
a9ceb36
test: 필드에 접근 제어자 추가
skylar1220 Oct 11, 2024
24b706b
fix: 하이라이트 줄 번호 계산 로직 및 변수명 수정
skylar1220 Oct 11, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,11 @@ public class HighlightController {
private final HighlightService highlightService;

@PostMapping("/v2/highlight")
public ResponseEntity<Void> highlight(@Valid @RequestBody HighlightsRequest request,
@SessionAttribute("reviewRequestCode") String reviewRequestCode) {
highlightService.highlight(request);
public ResponseEntity<Void> highlight(
@Valid @RequestBody HighlightsRequest request,
@SessionAttribute("reviewRequestCode") String reviewRequestCode
) {
highlightService.highlight(request, reviewRequestCode);
Copy link
Contributor

Choose a reason for hiding this comment

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

리뷰 컨트롤러처럼 개행을 맞추면 어떨까요?

    @GetMapping("/v2/reviews/{id}")
    public ResponseEntity<ReviewDetailResponse> findReceivedReviewDetail(
            @PathVariable long id,
            @SessionAttribute("reviewRequestCode") String reviewRequestCode
    ) {
        ReviewDetailResponse response = reviewDetailLookupService.getReviewDetail(id, reviewRequestCode);
        return ResponseEntity.ok(response);
    }

return ResponseEntity.ok().build();
Comment on lines +24 to 25
Copy link
Contributor

Choose a reason for hiding this comment

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

커밋 순서가,, 서비스 변경 사항은 포함돼있지 않았네요 😢

Copy link
Contributor Author

Choose a reason for hiding this comment

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

아차차😂

}
}
36 changes: 36 additions & 0 deletions backend/src/main/java/reviewme/highlight/domain/Highlight.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package reviewme.highlight.domain;

import jakarta.persistence.Column;
import jakarta.persistence.Embedded;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import lombok.AccessLevel;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Entity
@Table(name = "highlight")
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@EqualsAndHashCode(of = "id")
@Getter
public class Highlight {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

@Column(name = "answer_id", nullable = false)
private long answerId;

@Embedded
private HighlightPosition highlightPosition;
Copy link
Contributor

Choose a reason for hiding this comment

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

깔끔하다 👍👍👍


public Highlight(long answerId, long lineIndex, long startIndex, long endIndex) {
this.answerId = answerId;
this.highlightPosition = new HighlightPosition(lineIndex, startIndex, endIndex);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package reviewme.highlight.domain;

import jakarta.persistence.Column;
import jakarta.persistence.Embeddable;
import lombok.AccessLevel;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.NoArgsConstructor;
import reviewme.highlight.domain.exception.HighlightStartIndexExceedEndIndexException;
import reviewme.highlight.domain.exception.NegativeHighlightIndexException;

@Embeddable
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Getter
@EqualsAndHashCode
public class HighlightPosition {

@Column(name = "line_index", nullable = false)
private long lineIndex;

@Column(name = "start_index", nullable = false)
private long startIndex;

@Column(name = "end_index", nullable = false)
private long endIndex;

public HighlightPosition(long lineIndex, long startIndex, long endIndex) {
validatePositiveIndexNumber(startIndex, endIndex);
Copy link
Contributor

Choose a reason for hiding this comment

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

Positive은 0보다 큰 값을 의미합니다. NonNegative로 음이 아닌을 의미하면 어떨까요?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

오호 헷갈렸네요 반완!

validateEndIndexOverStartIndex(startIndex, endIndex);
this.lineIndex = lineIndex;
this.startIndex = startIndex;
this.endIndex = endIndex;
}

private void validatePositiveIndexNumber(long startIndex, long endIndex) {
if (startIndex < 0 || endIndex < 0) {
throw new NegativeHighlightIndexException(startIndex, endIndex);
}
}

private void validateEndIndexOverStartIndex(long startIndex, long endIndex) {
if (startIndex > endIndex) {
throw new HighlightStartIndexExceedEndIndexException(startIndex, endIndex);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package reviewme.highlight.domain.exception;

import lombok.extern.slf4j.Slf4j;
import reviewme.global.exception.BadRequestException;

@Slf4j
public class HighlightStartIndexExceedEndIndexException extends BadRequestException {

public HighlightStartIndexExceedEndIndexException(long startIndex, long endIndex) {
super("하이라이트 끝 위치는 시작 위치보다 같거나 커야 해요.");
log.info("Highlight start index exceed end index - startIndex: {}, endIndex: {}", startIndex, endIndex);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package reviewme.highlight.domain.exception;

import lombok.extern.slf4j.Slf4j;
import reviewme.global.exception.BadRequestException;

@Slf4j
public class NegativeHighlightIndexException extends BadRequestException {

public NegativeHighlightIndexException(long startIndex, long endIndex) {
super("하이라이트 위치는 1 이상의 수이어야 해요.");
log.info("Highlight index is a negative number - startIndex: {}, endIndex: {}", startIndex, endIndex);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package reviewme.highlight.repository;

import org.springframework.data.jpa.repository.JpaRepository;
import reviewme.highlight.domain.Highlight;

public interface HighlightRepository extends JpaRepository<Highlight, Long> {
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,65 @@
package reviewme.highlight.service;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import reviewme.highlight.domain.Highlight;
import reviewme.highlight.repository.HighlightRepository;
import reviewme.highlight.service.dto.HighlightIndexRangeRequest;
import reviewme.highlight.service.dto.HighlightRequest;
import reviewme.highlight.service.dto.HighlightedLineRequest;
import reviewme.highlight.service.dto.HighlightsRequest;
import reviewme.highlight.service.validator.HighlightValidator;
import reviewme.review.domain.Answer;
import reviewme.review.repository.AnswerRepository;
import reviewme.review.service.exception.ReviewGroupNotFoundByReviewRequestCodeException;
import reviewme.reviewgroup.repository.ReviewGroupRepository;

@Service
@RequiredArgsConstructor
public class HighlightService {

public void highlight(HighlightsRequest request) {
// TODO: implement method
private final HighlightRepository highlightRepository;
private final ReviewGroupRepository reviewGroupRepository;
private final AnswerRepository answerRepository;

private final HighlightValidator highlightValidator;

@Transactional
public void highlight(HighlightsRequest request, String reviewRequestCode) {
Copy link
Contributor

Choose a reason for hiding this comment

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

메서드명 그냥 하이라이트.. 괜찮을까요? 도메인명하고도 동일한데

Copy link
Contributor Author

Choose a reason for hiding this comment

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

리팩토링 pr에서 editHighlight로 변경하였습니다~

long reviewGroupId = reviewGroupRepository.findByReviewRequestCode(reviewRequestCode)
.orElseThrow(() -> new ReviewGroupNotFoundByReviewRequestCodeException(reviewRequestCode))
.getId();

highlightValidator.validate(request, reviewGroupId);
deleteOldHighlight(request.questionId(), reviewGroupId);
saveNewHighlight(request);
}

private void deleteOldHighlight(long questionId, long reviewGroupId) {
Copy link
Contributor

Choose a reason for hiding this comment

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

오래된... 보단 이전 어때요?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

beforeHighlight로 수정!

Set<Answer> answersByReviewGroup = answerRepository.findAllByReviewGroupId(reviewGroupId);
List<Long> answersByReviewQuestion = answersByReviewGroup.stream()
.filter(answer -> answer.getQuestionId() == questionId)
.map(Answer::getId)
.toList();

highlightRepository.deleteAllById(answersByReviewQuestion);
}

private void saveNewHighlight(HighlightsRequest highlightsRequest) {
List<Highlight> highlights = new ArrayList<>();
for (HighlightRequest highlight : highlightsRequest.highlights()) {
for (HighlightedLineRequest line : highlight.lines()) {
for (HighlightIndexRangeRequest range : line.ranges()) {
Highlight highLight = new Highlight(highlight.answerId(),
line.index(), range.startIndex(), range.endIndex());
highlights.add(highLight);
}
}
}
highlightRepository.saveAll(highlights);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package reviewme.highlight.service.exception;

import lombok.extern.slf4j.Slf4j;
import reviewme.global.exception.BadRequestException;

@Slf4j
public class HighlightDuplicatedException extends BadRequestException {

public HighlightDuplicatedException(long answerId, long lineIndex, long startIndex, long endIndex) {
super("중복된 하이라이트는 생성할 수 없어요.");
log.info("Highlight is duplicated - answerId: {}, lineIndex: {}, startIndex: {}, endIndex: {}",
answerId, lineIndex, startIndex, endIndex);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package reviewme.highlight.service.exception;

import lombok.extern.slf4j.Slf4j;
import reviewme.global.exception.BadRequestException;

@Slf4j
public class InvalidHighlightLineIndexException extends BadRequestException {

public InvalidHighlightLineIndexException(long submittedLineIndex, long maxLineIndex) {
super("줄 번호는 %d 이하여야해요.".formatted(maxLineIndex));
log.info("Line index is out of bound - maxIndex: {}, submittedLineIndex: {}", maxLineIndex, submittedLineIndex);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package reviewme.highlight.service.exception;

import java.util.Collection;
import lombok.extern.slf4j.Slf4j;
import reviewme.global.exception.BadRequestException;

@Slf4j
public class SubmittedAnswerAndProvidedAnswerMismatchException extends BadRequestException {

public SubmittedAnswerAndProvidedAnswerMismatchException(Collection<Long> providedAnswerIds,
Collection<Long> submittedAnswerIds) {
super("제출된 응답이 제공된 응답과 일치하지 않아요.");
log.info("SubmittedAnswer and providedAnswer mismatch - providedAnswerIds: {}, submittedAnswerIds: {}",
providedAnswerIds, submittedAnswerIds);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
package reviewme.highlight.service.validator;

import java.util.List;
import java.util.Set;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;
import reviewme.highlight.service.dto.HighlightRequest;
import reviewme.highlight.service.dto.HighlightedLineRequest;
import reviewme.highlight.service.dto.HighlightsRequest;
import reviewme.highlight.service.exception.InvalidHighlightLineIndexException;
import reviewme.highlight.service.exception.SubmittedAnswerAndProvidedAnswerMismatchException;
import reviewme.question.repository.QuestionRepository;
import reviewme.review.domain.TextAnswer;
import reviewme.review.repository.AnswerRepository;
import reviewme.review.repository.TextAnswerRepository;
import reviewme.review.service.exception.AnswerNotFoundByIdException;
import reviewme.review.service.exception.SubmittedQuestionAndProvidedQuestionMismatchException;
import reviewme.reviewgroup.repository.ReviewGroupRepository;

@Component
@RequiredArgsConstructor
public class HighlightValidator {

private final AnswerRepository answerRepository;
private final TextAnswerRepository textAnswerRepository;
private final QuestionRepository questionRepository;
private final ReviewGroupRepository reviewGroupRepository;

public void validate(HighlightsRequest request, long reviewGroupId) {
validateReviewGroupContainsQuestion(request, reviewGroupId);
validateReviewGroupContainsAnswer(request, reviewGroupId);
validateQuestionContainsAnswer(request);
validateLineIndex(request);
// TODO: 중복 요청 검증 추가 예정
Copy link
Contributor

Choose a reason for hiding this comment

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

여기 부분이 다 리팩터링 예정인가요?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

리팩토링 pr에서 제거했어요!

}
Copy link
Contributor

Choose a reason for hiding this comment

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

validateAnswerByReviewGroup, validateQuestionByReviewGroup, validateAnswerByQuestion

이 부분은 highlight가 연관된 것들을 id로 가지고 있어서 절차적으로 검증할 수 밖에 없는 부분인데요. 리뷰 그룹과 질문으로 답변을 가져오는 것으로 한번에 검증과 동시에 자원을 가져올 수 있지 않을까요? 로직과 쿼리 한 번으로 감당할 수 있을 것 같아요.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

리팩토링 pr에서 반영하겠습니다!


private void validateReviewGroupContainsQuestion(HighlightsRequest request, long reviewGroupId) {
long templateId = reviewGroupRepository.findById(reviewGroupId)
Copy link
Contributor

Choose a reason for hiding this comment

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

HighlightService에서 찾은 리뷰 그룹의 아이디를 통해서 보낸 id를 또 리뷰 그룹 repo에서 찾는 것은 비효율적인 것 같아요.

.orElseThrow()
.getTemplateId();
Set<Long> providedQuestionIds = questionRepository.findAllQuestionIdByTemplateId(templateId);
long submittedQuestionId = request.questionId();

if (!providedQuestionIds.contains(submittedQuestionId)) {
throw new SubmittedQuestionAndProvidedQuestionMismatchException(submittedQuestionId, providedQuestionIds);
}
}

private void validateReviewGroupContainsAnswer(HighlightsRequest request, long reviewGroupId) {
Set<Long> providedAnswerIds = answerRepository.findIdsByReviewGroupId(reviewGroupId);
List<Long> submittedAnswerIds = request.highlights()
.stream()
.map(HighlightRequest::answerId)
.toList();

if (!providedAnswerIds.containsAll(submittedAnswerIds)) {
throw new SubmittedAnswerAndProvidedAnswerMismatchException(providedAnswerIds, submittedAnswerIds);
}
}

private void validateQuestionContainsAnswer(HighlightsRequest request) {
Set<Long> providedAnswerIds = answerRepository.findIdsByQuestionId(request.questionId());
List<Long> submittedAnswerIds = request.highlights()
.stream()
.map(HighlightRequest::answerId)
.toList();

if (!providedAnswerIds.containsAll(submittedAnswerIds)) {
throw new SubmittedAnswerAndProvidedAnswerMismatchException(providedAnswerIds, submittedAnswerIds);
}
}

private void validateLineIndex(HighlightsRequest request) {
Copy link
Contributor

@Kimprodp Kimprodp Oct 10, 2024

Choose a reason for hiding this comment

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

이 부분도 객체의 책임으로 할 수 있는 방법이 없을까요?

(개인적으로 답변을 함께 생성자에 넘겨서 의존하지 않고 answer를 사용하게 하거나 답변에 대한 index 길이 검증 책임을 가지는 클래스가 있어도 될 것 같아요)

Copy link
Contributor

Choose a reason for hiding this comment

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

일급 컬렉션을 통해도 좋겠네요. 절차지향을 빌렸지만, 그래도 주는 객체지향임을 명심합시다 ⛰️

Copy link
Contributor

Choose a reason for hiding this comment

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

저도 동의합니다~

Copy link
Contributor Author

Choose a reason for hiding this comment

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

리팩토링 pr에서 반영하겠습니다!

for (HighlightRequest highlight : request.highlights()) {
TextAnswer textAnswer = textAnswerRepository.findById(highlight.answerId())
.orElseThrow(() -> new AnswerNotFoundByIdException(highlight.answerId()));
long maxLineIndex = textAnswer.getContent().lines().count();
Copy link
Contributor

Choose a reason for hiding this comment

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

오 이렇게 개행이 된 라인 수를 가져올 수 있군요! 야미~


for (HighlightedLineRequest line : highlight.lines()) {
long submittedLineIndex = line.index();
if (maxLineIndex < submittedLineIndex) {
throw new InvalidHighlightLineIndexException(submittedLineIndex, maxLineIndex);
}
}
Copy link
Contributor

Choose a reason for hiding this comment

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

이 if 문 수정이 필요해보여요.
지금 maxLineIndex 는 서술형 답변의 "라인 수(마지막 idx + 1)"을 나타내기 때문에 <= 여야 합니다.
그리고, maxLineIndex 라는 변수명을 answerLineCount 혹은 existingLineNumbers같은 걸로 바꾸는 것도 의미 전달이 더 잘 될 것 같아요.


그리고 테스트 코드에서도 아래 부분 수정해주세요!

long answerLineCount = textAnswer.getContent().lines().count();
HighlightedLineRequest highlightedLineRequest = new HighlightedLineRequest(answerLineCount + 1, List.of()); // ❗️이 부분을 answerLineCount로 바꿔야 경계값이 됩니다.
HighlightRequest highlightRequest = new HighlightRequest(textAnswer.getId(), List.of(highlightedLineRequest));
HighlightsRequest highlightsRequest = new HighlightsRequest(questionId, List.of(highlightRequest));

Copy link
Contributor Author

Choose a reason for hiding this comment

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

비교대상 두개 모두 index 개념이어야 쉽게 이해갈 것 같아서 providedMaxLineIndex로 해봤는데 어떤가요?
저 경계값은 고쳐야겠네요! 반완!

Copy link
Contributor

Choose a reason for hiding this comment

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

음~ 좋네용 😋

}
}
Copy link
Contributor

Choose a reason for hiding this comment

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

레벨1, 2에서 어떻게 리팩터링했는지 돌아보면 실마리가 보일거예요~

Copy link
Contributor Author

Choose a reason for hiding this comment

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

해볼게요!

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package reviewme.review.repository;

import java.util.Set;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.stereotype.Repository;
import reviewme.review.domain.Answer;

@Repository
public interface AnswerRepository extends JpaRepository<Answer, Long> {

@Query(value = """
SELECT a.id FROM Answer a
JOIN Review r
ON a.reviewId = r.id
WHERE r.reviewGroupId = :reviewGroupId
""")
Set<Long> findIdsByReviewGroupId(long reviewGroupId);

@Query(value = """
SELECT a FROM Answer a
JOIN Review r
ON a.reviewId = r.id
WHERE r.reviewGroupId = :reviewGroupId
""")
Set<Answer> findAllByReviewGroupId(long reviewGroupId);

@Query(value = """
SELECT a.id FROM Answer a
JOIN Question q
ON a.questionId = q.id
WHERE q.id = :questionId
""")
Set<Long> findIdsByQuestionId(long questionId);
}
Copy link
Contributor

Choose a reason for hiding this comment

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

지금 아루의 PR이 올라와 있으니 미리 JPQL로 바꾸죠!

Copy link
Contributor Author

Choose a reason for hiding this comment

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

반영완!

Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package reviewme.review.service.exception;

import lombok.extern.slf4j.Slf4j;
import reviewme.global.exception.NotFoundException;

@Slf4j
public class AnswerNotFoundByIdException extends NotFoundException {

public AnswerNotFoundByIdException(long answerId) {
super("답변을 찾을 수 없어요.");
log.info("Answer not found by id - answerId: {}", answerId);
}
}
Loading