주특기 숙련 주간 개인 과제
이번 주간 개인 과제는 저번 CRUD API에 다른 기능들을 추가하는 것이다.
사실 주말 내로 강의를 다 듣고 과제를 시작한 건 어제였지만,
어제의 나는 밤샘 이슈로 제정신이 아닌 상황이었기에..^^
오늘에서야 제대로 정리해본다.
🚩 Goal: "회원가입, 로그인, 댓글 작성/조회/수정/삭제 기능이 추가된 나만의 항해 블로그 백엔드 서버 만들기"
간단히 말하면, 이렇다.
CRUD API + JWT 로그인/회원가입 (Lv1) + 댓글 CRUD API, 회원 권한 부여, 예외처리 (Lv2)
어제 JWT를 이용한 회원가입과 로그인을 마무리했고,
오늘 댓글 CRUD API를 마무리했다.
큰 범주에서 보면 저번 주와 같은 CRUD인데
JPA를 이용해서 게시글과 댓글의 연관관계를 정의하는 게 쉽지 않았다.
다음은 오늘 겪었던 이슈들이다.
오늘의 궁금증
짚고 넘어가자 Optional
- Optional이란? null이 올 수 있는 값을 감싸는 Wrapper 클래스로 참조하더라도 NPE(NullPointerException)가 발생하지 않도록 도와준다.
Optional을 어디에서 사용할까?
Spring Data JPA 사용 시 findById의 리턴 타입은 Optional로 고정되어 있다.
CrudRepository에서 확인해보자.
package org.springframework.data.repository;
import java.util.Optional;
import org.springframework.dao.OptimisticLockingFailureException;
...
@NoRepositoryBean
public interface CrudRepository<T, ID> extends Repository<T, ID> {
...
Optional<T> findById(ID id);
...
}
게시글 작성 시 토큰을 검증하고, 해당 사용자 정보를 DB에서 조회하는 부분이다.
orElseThrow()를 이용하여 Exception을 던져주고 있다.
// 토큰에서 가져온 사용자 정보를 사용하여 DB 조회
User user = userRepository.findByUsername(claims.getSubject()).orElseThrow(
() -> new IllegalArgumentException("사용자가 존재하지 않습니다.")
);
아직은 익숙하지 않은 문법이라 더 다양한 케이스를 마주하면서 공부해야 할 것 같다.
📚 참고자료
연관관계 매핑.. 그거 어떻게 하는 건데?
- 연관관계 매핑이란? 객체의 참조와 테이블의 외래 키를 매핑하는 것을 의미한다.
JPA에서는 연관 관계에 있는 상대 테이블의 PK를 멤버 변수로 갖지 않고, 엔티티 객체 자체를 통째로 참조한다.
1. 방향
- 단방향 관계 : 두 엔티티가 관계를 맺을 때, 한쪽의 엔티티만 참조하고 있는 것을 의미
- 양방향 관계 : 두 엔티티가 관계를 맺을 때, 양 쪽이 서로 참조하고 있는 것을 의미
데이터 모델링에서는 관계를 맺어주기만 하면 자동으로 양방향 관계가 되어 서로 참조하지만,
객체지향 모델링에서는 구현하고자 하는 서비스에 따라 단방향 관계인지, 양방향 관계인지 적절한 선택을 해야 한다.
2. 다중성
관계에 있는 두 엔티티는 다음 중 하나의 관계를 갖는다.
- ManyToOne : 다대일 ( N : 1 )
- OneToMany : 일대다 ( 1 : N )
- OneToOne : 일대일 ( 1 : 1 )
- ManyToMany : 다대다 ( N : N )
예를 들어 하나의 Team은 여러 Member를 구성원으로 갖고 있으므로 Team 입장에서는 Member와 일대다 관계이며,
Member의 입장에서는 하나의 Team에 속하므로 다대일 관계이다.
즉, 어떤 엔티티를 중심으로 상대 엔티티를 바라보느냐에 따라 다중성이 다르게 된다.
3. 연관관계의 주인 (Owner)
객체를 양방향 연관관계로 만들면 연관관계의 주인을 정해야 한다.
연관관계를 갖는 두 테이블에서 외래 키를 갖게 되는 테이블이 연관관계의 주인이 된다.
연관관계의 주인만이 외래 키를 관리(등록, 수정, 삭제) 할 수 있고, 주인이 아닌 엔티티는 읽기만 할 수 있다.
📚 참고자료
오늘의 에러
No serializer found for class com.sparta.crud.dto.CommentToDto and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS) (through reference chain: com.sparta.crud.dto.BoardListResponseDto["boradList"]->java.util.ArrayList[0]->com.sparta.crud.dto.BoardToDto["commentList"]->java.util.ArrayList[0])
게시글을 조회하면서 해당 게시글에 달린 댓글까지 전부 조회해오는 로직을 구현하다 위와 같은 에러를 마주했다.
게시글 Entity와 DTO에 각각 댓글이 들어갈 자리를 List로 마련해놓고 for문을 돌며 DTO로 변환하여 넣어주었는데
도대체 어디서 잘못된 건지 감이 오지 않아 기술 매니저님께 여쭤보았다.
"DTO 내에서 저런 식으로 비즈니스와 관련된 로직은 구현하지 않아요.
DTO는 딱 데이터 전송만을 위한 기능을 해야 해요. 해당 로직을 Service에서 구현해보세요.
그리고 빌더 패턴을 공부해보세요!"
매니저님이 언급하셨던 부분은 다음과 같다.
public BoardToDto(Board board) {
this.id = board.getId();
this.title = board.getTitle();
this.username = board.getUsername();
this.content = board.getContent();
this.createdAt = board.getCreatedAt();
this.modifiedAt = board.getModifiedAt();
// 바로 이 부분!
List<CommentToDto> commentList = new ArrayList<>();
for (Comment comment : board.getComments()) {
commentList.add(new CommentToDto(comment));
}
}
나는 나름 DTO로 변환해주는 로직이라고 생각했는데 아무래도 이런 식으로는 사용하지 않는 모양이다.
매니저님의 말씀대로 해당 로직을 그대로 Service로 옮겨 실행해보았지만, 여전히 같은 에러가 났다.
에러 메시지로 열심히 구글링 하던 중 스택오버플로우에서 Getter와 관련된 내용을 보고 '설마..?' 하며 코드를 다시 보았다.
진짜 맙소사🤦♀️
@Getter 어노테이션을 빼먹어서 값이 들어오지 않았던 것이었다....
그것만 추가해주니 아주 잘 작동이 되었다^^
(이후에도 @Getter를 빼먹은 DTO를 또 발견하고 이마를 짚었다)
객체지향 스터디 첫 모임
[1장 사람을 사랑한 기술] 부분을 읽고 각자 흥미로웠던 주제를 정해 간단히 발표를 하기로 했다.
나는 Java라는 언어가 어떤 배경에서 발전을 했는지,
그 배경과 연관 지어 어떤 특징들을 갖고 있는지에 대해 정리하고 공유했다.
다른 팀원분들의 발표를 들으면서 타인의 생각 회로를 엿볼 수 있어 좋았고,
어떻게 하다 보니 겹치지 않는 다양한 주제로 이야기 나눠볼 수 있어서 진짜 재밌었다.
책 내용도 어렵지 않고, 팀원분들도 다 좋고.. 스터디하길 진짜 잘했다는 생각이 들었다😊
오늘의 나는
참 많이도 졸았다.
보다 못한 조원분이 가서 좀 자고 오라고 할 정도로..
버티다 못해 결국 냅다 가서 자버렸다.
생각도 하기 전에 몸이 먼저 침대로 직행해버렸지만,
가급적 정규 시간엔 이런 일이 없도록 하자.
꿀잠 자고 저녁 시간에 뽝 집중해서 개안 과제의 댓글 기능을 구현했다.
우리 조 3명뿐이라 조촐하지만.. 에러를 만날 때마다 바로 화면 공유하면서
집단지성으로 해결해버리고 진짜 멋지다.
내일은 Lv2의 남은 부분인 권한 부여와 예외 처리를 마무리하고,
꼭 조원분들과 과제에 대한 코드 리뷰를 할 수 있으면 좋겠다!
'📝 TIL' 카테고리의 다른 글
[TIL] 4주차 주특기 숙련ㅣSpring 시험 (0) | 2022.12.08 |
---|---|
[TIL] 4주차 주특기 숙련ㅣ권한부여, 예외처리 (0) | 2022.12.07 |
[TIL] 4주차 주특기 숙련ㅣ조각모음 (3) | 2022.12.05 |
[TIL] 3주차 주특기 숙련ㅣ컨디션 난조 (2) | 2022.12.03 |
[TIL] 3주차 주특기 숙련ㅣ주간 시작 (0) | 2022.12.02 |