1 minute read

Daily TODO

  • Answer CRUD 구현 완성
  • 추가 - User CRUD 구현
    • CRD 구현완료, Update 내일 구현 예정
  • Update, Comment Entity까지 구현 필요함
  • JWT 이용한 login & logout 구현
  • OAuth 구현
  • H2 말고 MySQL이랑 연결 (영구적인 데이터베이스)
  • 테스트 데이터도 생성하면 더 좋지 않을까 생각함!!
  • 금요일에 AWS 써서 배포까지 할 수 있으면 좋을 거 같다

메모 & TIL:

Pre-project

  • 하면서 이상하게 자꾸 patchAnswer에서 오류가 났다 (이거만 한 6시간 본 듯)
  • 자꾸 널포인터 오류가 난대서 매핑의 문제인줄로 알았으나…… 전혀 아니었다!
  • 결론부터 보자면 Repository에서 가져온 객체는 여기에(Answer) 매핑된 객체(Vote)가 초기화 안됐을수도 있으니까 그부분 처리를 해줘야 했음 (근데 왜 매핑된 객체를 옵셔널 바인딩으로 하면 처리가 잘 안되는지 모르겟음)
public Answer updateAnswer(Answer answer, Long answerId, Long voteCnt) {  
    Answer findAnswer = findVerifiedAnswer(answerId);  
  
    Optional.ofNullable(answer.getContent())  
            .ifPresent(content -> findAnswer.setContent(content));  
    Optional.ofNullable(answer.getAccepted())  
            .ifPresent(accepted -> findAnswer.setAccepted(accepted));  
  
    if (findAnswer.getVote() == null) {  
        findAnswer.setVote(new Vote());  
    }  
  
    findAnswer.setVoteCount(findAnswer.getVoteCount() + voteCnt);  
    findAnswer.setModifiedAt(LocalDateTime.now()); // 최종 수정시간 현재 시간으로 변경  
  
    return answerRepository.save(findAnswer);  
}
  • 그리고 dto에서 엔티티로 변환한 객체에서 식별자(Id) 가져오려고 하면 안되서 (지금 생각해보니 dto에 id를 안 받게 만들었으니 당연함 ㅎㅎ 머쓱…) updateAnswer 메소드에 직접 파라미터로 넣어줬다. voteCnt도 마찬가지!
@PatchMapping("/{answer-id}")  
public ResponseEntity patchAnswer(@PathVariable("answer-id") @Positive long answerId,  
        @Valid @RequestBody AnswerPatchDto answerPatchDto){  
    Answer answer = answerService  
            .updateAnswer(mapper.answerPatchDtoToAnswer(answerPatchDto),  
            answerId,  
            answerPatchDto.getVoteCnt());  
    return new ResponseEntity<>(  
            new SingleResponseDto<>(mapper.answerToAnswerResponseDto(answer)), HttpStatus.OK);  
}
  • 그리고 객체 여러개 엮여잇으니까 매핑해주자.
public interface AnswerMapper {
 ...
	@Mapping(target = "vote.voteCnt", source = "voteCnt")  
	Answer answerPatchDtoToAnswer(AnswerPatchDto answerPatchDto);
}
  • Answer 업데이트할때 매핑된 객체(Vote)의 필드 변수 값 voteCnt도 같이 업데이트하고 싶어요~ 할때 이런식으로 매핑해주면 된다.

유사한 기능이 있다면 제너릭을 활용하자

  • Vote 객체가 질문과 답변 객체 둘 다에 쓸거라 고민하다가 제너릭을 도입해서 아주 사알짝 리팩토링을 했다.
package com.codestates.PreProject.vote;  
  
import com.codestates.PreProject.answer.entity.Answer;  
import lombok.Getter;  
import lombok.NoArgsConstructor;  
import lombok.Setter;  
  
import javax.persistence.*;  
  
@Getter  
@Setter  
@NoArgsConstructor  
@Entity  
public class Vote <T> {  
    @Id  
    @GeneratedValue(strategy = GenerationType.IDENTITY)  
    private Long voteId;  
  
    @Column(nullable = false)  
    public Long voteCnt = 0L;  
  
//    @OneToOne  
//    @JoinColumn(name = "ANSWER_ID")  
//    private Answer answer;  
  
    @OneToOne  
    // mapping은 각 구현체에서...  
    private T content;  
  
//    public void setAnswer(Answer answer){  
//        this.answer = answer;  
//    }  
  
    public void setContent(T content){  
        this.content = content;  
    }  
}
  • 기존 코드에서 Answer이 잇던 부분을 제너릭으로 바꿨다. 바꿔도 정상작동한다. 다만 구현체는 만들어줘야 한다
package com.codestates.PreProject.vote;  
import com.codestates.PreProject.answer.entity.Answer;  
import lombok.Getter;  
import lombok.NoArgsConstructor;  
import lombok.Setter;  
  
import javax.persistence.Entity;  
import javax.persistence.OneToOne;  
  
@Entity  
@Getter  
@Setter  
@NoArgsConstructor  
public class AnswerVote extends Vote<Answer>{  
    @OneToOne  
    private Answer answer;  
  
}

이런 식으로… 구현체의 클래스도 만들어주면 기존이랑 똑같이 요청 날려도 정상적으로 수행된다!

Leave a comment