마지막 개인과제 제출
2024.07.05.(금)
개인과제
* 오늘 해결한 내용
- 문제 상황 1 : @ActiveProfiles("test") 이렇게 사용했음에도 application-test.properties가 적용이 안 되었음
- 해결 방법 1
- main package로 옮겨서 실행해보려고 하면서 h2 라이브러리가 build.gradle에 적용되지 않았음을 발견하고 아래의 코드를 적용
- 사진의 resources가 test > java > com.sparta.greeypeople에 위치하고 있었기에 test > resources로 옮겨줌
runtimeOnly 'com.h2database:h2'
- 문제 상황 2
맥북으로 노트북을 변경하면서 인텔리제이를 새로 깔고 세팅하는 과정에서 Java version이 22 밖에 뜨지 않아서 22로 했더니 build.gradle에서도 변경하라고 해서 22로 했다가.. 테스트 코드를 동작하는 과정에서 아래와 같은 에러가 발생했다. 물론 실행했을 때는 문제 없다가 테스트 코드를 실행했을 때만 문제가 발생한다.
Target JRE version (22.0.1) does not match project JDK version (Amazon Corretto 21.0.3 - aarch64), will use sources from JDK: openjdk-22
- 해결 방법 2
setting에서 Download JDK?를 누르고 version을 17로 변경해서 세팅해주면 된다.
그러고 build.gradle도 아래와 같이 17로 변경해주면 완료!
java {
toolchain {
languageVersion = JavaLanguageVersion.of(17)
}
}
- 문제 상황 3 : 테스트 코드에서 id를 넣어 줄 수 없음
entity에서 id의 값을 넣어주는 생성자를 만들지도 않았고, 빌더를 사용하지도 않았다.
이런 경우에서는 id의 값이 null이기에 문제가 발생한다...
- 해결 방법 3
1. application-test.properties와 같이 테스트용 DB를 만들어서 직접 데이터를 넣어준다.
2. 다른 방법이 하나 더 있었는데.. 블로그 작성하다가 날아가서 기억이 안나는 걸?
-> 객체 자체를 만드는 방법 ex) 빌더 패턴, 생성자
내가 채택한 방법은 1번이다.
원래 사용하려던 @Mock은 주석처리하고 @Autowired로 변경해주었다.
// @Mock
@Autowired
ReviewRepository reviewRepository;
// @Mock
@Autowired
StoreRepository storeRepository;
* 개인과제 진행 중의 고민
계층형으로 패키지를 분리해서 작업할 때는 문제가 없었는데.. 도메인형으로 변경하고 나서는 서로 연관된 테이블이 너무 많아서 어떤 도메인에 넣어야 할지 고민하게 되었다.
예를 들어, 유저가 좋아요를 해놓은 게시글(지난 프로젝트에서는 메뉴)이나 댓글(지난 프로젝트에서는 리뷰)은 유저의 패키지에 넣어야 하는 건지 아니면 좋아요의 패키지에 넣어야 하는 건지 생각하게 되었다. 결론적으로는 유저가 사용하게 되는 기능이기에 프론트까지 생각한다면 유저의 패키지에 넣는게 맞다고 생각해서 유저 패키지에 넣었다.
* 기술 질문
- Q : JPA와 Hibernate의 차이점은 무엇인가요?
- JPA는 표준 인터페이스이고, Hibernate는 그 구현체 중 하나입니다.
- JPA는 독립적인 ORM 표준을 제공하며, Hibernate는 JPA를 구현하면서도 추가 기능을 포함하는 ORM 프레임워크입니다.
- Q : QueryDSL을 사용하여 복잡한 동적 쿼리를 작성하는 방법을 설명해 주세요.
- QueryDSL 설정: 프로젝트에 QueryDSL 의존성을 추가하고, 엔티티 클래스에 대한 Q 클래스를 생성합니다.
- 동적 쿼리 작성: JPAQueryFactory와 BooleanBuilder를 사용하여 조건에 따라 동적으로 쿼리를 작성합니다.
- 타입 안전성: QueryDSL은 컴파일 타임에 쿼리의 타입을 체크하여 런타임 오류를 줄입니다.
- QueryDSL 설정: 프로젝트에 QueryDSL 의존성을 추가하고, 엔티티 클래스에 대한 Q 클래스를 생성합니다.
- Q : JPA에서 Lazy Loading과 Eager Loading의 차이점은 무엇인가요? 각각의 장단점에 대해 설명해 주세요.
- Lazy Loading: 데이터가 실제로 필요할 때 로드하는 방식. 메모리 효율성과 성능 최적화 측면에서 유리하지만, 추가 쿼리와 LazyInitializationException 문제를 유발할 수 있습니다.
- Eager Loading: 엔티티 조회 시점에 관련 데이터를 모두 로드하는 방식. 간편성과 일관성 측면에서 유리하지만, 메모리 사용량이 많아지고 불필요한 데이터 로딩으로 성능 저하가 발생할 수 있습니다.
- Lazy Loading: 데이터가 실제로 필요할 때 로드하는 방식. 메모리 효율성과 성능 최적화 측면에서 유리하지만, 추가 쿼리와 LazyInitializationException 문제를 유발할 수 있습니다.
- Q : 좋아요 기능을 구현할 때, 특정 사용자가 특정 게시글을 이미 좋아요 했는지 확인하는 방법을 설명해 주세요.
- 엔티티 설계: User, Post, Like 엔티티를 정의하여, Like 엔티티가 User와 Post 사이의 다대다 관계를 나타냅니다.
- 좋아요 여부 확인: LikeRepository에 findByUserAndPost 메서드를 구현하여, 특정 사용자와 특정 게시글에 대한 좋아요 여부를 조회합니다.
- 서비스 및 컨트롤러: 서비스에서 isPostLikedByUser 메서드를 통해 좋아요 여부를 확인하고, 컨트롤러에서 이 서비스를 호출하여 결과를 반환합니다.
- 엔티티 설계: User, Post, Like 엔티티를 정의하여, Like 엔티티가 User와 Post 사이의 다대다 관계를 나타냅니다.
- Q : JPA에서 N+1 문제를 해결하기 위한 방법을 설명해 주세요.
- Fetch Join 사용: JPQL의 JOIN FETCH를 통해 한 번의 쿼리로 관련 엔티티를 로드합니다.
- Entity Graph 사용: @EntityGraph를 통해 쿼리 시점에 페치 전략을 지정합니다.
- Batch Size 설정: @BatchSize 또는 글로벌 설정을 통해 배치 페치 크기를 설정합니다.
- Subselect Fetching 사용: Hibernate의 @Fetch(FetchMode.SUBSELECT)를 통해 서브셀렉트 방식으로 로드합니다.
- Fetch Join 사용: JPQL의 JOIN FETCH를 통해 한 번의 쿼리로 관련 엔티티를 로드합니다.
- Q : 게시글 조회 시 댓글과 좋아요 수를 함께 조회하는 방법을 설명해 주세요.
- JPQL 사용:
JPQL 쿼리를 작성하여 게시글과 댓글을 페치 조인하고, 좋아요 수를 별도의 쿼리로 조회합니다.
서비스 레이어에서 쿼리 결과를 조합하여 필요한 정보를 제공합니다. - QueryDSL 사용:
QueryDSL 설정을 통해 타입 안전한 쿼리를 작성합니다.
커스터마이징된 리포지토리를 통해 게시글, 댓글, 좋아요 수를 함께 조회합니다.
서비스 레이어에서 쿼리 결과를 조합하여 필요한 정보를 제공합니다.
- JPQL 사용:
* 구현한 내용
지난 팀프로젝트에서 이미 했던 내용을 제출했기에 필수구현 1개, 추가구현 1개를 해서 냈다.
계층별로 나누어서 테스트 코드를 작성하는 것에 중점을 두었기에 구현 자체는 많이 하지 못했다.
그리고 QueryDSL을 적용해보는 것까지가 목표였는데 적용하지 못하고 제출했다.
* 개인과제 레파지토리
오늘의 회고
- 12시간 중 얼마나 몰입했는가?
오전에 튜터님께 또 테스트 코드 관련해서 질문 갔다가
점심 먹고 오후에 식곤증으로 매니저님 튜터님이랑 얘기했더니 시간이 다 지났다.
오늘도 튜터님께 질문 갔던 30분에서 1시간 정도를 가장 집중하지 않았나 싶다.
- 오늘의 생각
내가 목표하는 개발자는 테스트 코드를 잘 작성하며 예외처리를 잘 하고 성능향상을 목표로하는 개발자였는데..
오늘부로 테스트 코드? 그게 머죠??? 난 몰라. 이제 난 예외처리 잘 하고 성능향상을 목표로하는 개발자할거야.
디버그는.. 또 튜터님께 갔다가 잘 사용하면 좋지만 상황에 따라서는 엄청나게 유용하다!까지는 아닐 수도 있다고..
뭐 암튼!
개인과제는 필수 1개, 추가 1개를 완료했다. 둘 다 지난 팀 과제에서 해놨던 터라 살짝만 수정하면 됐다.
이번 과제는 지난 개인과제에서 진행하지 못했던 테스트 코드를 잡고 가기 위해 하나에만 중점을 두었다.
그리고 재제출 있을 줄 알고 천천히 했는데.. 재제출이 없는 줄 몰랐지!
주말에 QueryDSL을 이용해서 필수까지만이라도 진행해보려구 한다!
- 내일 학습할 것은 무엇인지
QueryDSL을 이용한 개인과제 필수 구현하기
자격증 공부, 책 읽기, 면접 준비...