-
JPA에서, Many To One 관계의 Post 요청에서 주의할 점Back-End/JPA 2022. 8. 25. 11:27728x90
Review 테이블이 있고, 리뷰와 함께 보여질 리뷰이미지를 의미하는 ReviewImage 테이블이 있다고 하자.
하나의 리뷰에 여러 개의 이미지를 달 수 있으므로, 이들은 1 대 다 관계이다.
리뷰를 post하는 서비스의 RequestDto는 다음과 같다.
{ "title" : "맛있어요", "content" : "또 가고 싶습니다.", "reviewImages" : [{ "url" : "https://naver.com" }] }
postReview 서비스는 다음과 같다.
@Transactional public UUID postReview(CreateReviewRequestDto dto){ Review review = Review.ReviewBuilder() .title(dto.getTitle()) .content(dto.getContent()) .build(); for(CreateReviewRequestDto.ReviewImage reviewImage : dto.getReviewImages()){ review.getReviewImages().add(ReviewImage.ReviewImageBuilder().url(reviewImage.getUrl()).review(review).build()); } return reviewRepository.save(review).getId(); }
이 때, 빌더 패턴을 통해 review 객체를 만드는데
@OneToMany(mappedBy = "review", cascade = CascadeType.ALL) @Builder.Default private List<ReviewImage> reviewImages = new ArrayList<>();
이처럼 빌더에서 해당 필드에 값을 주지 않았을 때 들어갈 기본값으로 arrayList 컬렉션을 주도록 설정한다.
이 후, dto의 이미지를 순회하면서 리뷰 엔티티의 리뷰이미지 필드에 ReviewImage 인스턴스들을 추가한다.
여기서 중요한 포인트는
1. ReviewImage의 Review 필드에도 Review 인스턴스를 넣어주어야 한다는 것이다.
그렇지 않으면 실제 DB에 해당 entity가 들어갈 때, ReviewImage의 Foreign key에 null값이 들어가고 만다.
2. ReviewImage 필드에 cacade 옵션을 주어야 한다.
그렇지 않을 경우, reviewImage 테이블에 아무 row값도 들어가지 않는다.
이는 reviewImage 객체가 persist 상태가 아니어서 그런 것이므로, review의 List필드에 객체를 추가할 때 reviewImage도 함께 영속상태가 되도록 cascade 옵션을 주어야 한다.
3. 기본적으로 X to One 관계는 fetch타입을 LAZY로 주어야한다. 그래야 N+1 문제를 방지할 수 있다.
만약 리뷰 조회 시 리뷰 이미지를 갖고오고 싶다면, fetch join을 통해 가져온다.
'Back-End > JPA' 카테고리의 다른 글
JPA의 연관관계에 대한 고찰 (0) 2022.11.18 JPA Auditing과 MappedSuperClass 활용 (0) 2022.09.14 JPA의 entity update는 어떻게 이루어질까? (0) 2022.05.03