[main-project] 0315

박채은·2023년 3월 14일

Project

목록 보기
11/21

추가로 Update 쿼리 발생하는 이유

발단

좋아요 기능을 구현하고 있었다.

PrfPost

@NoArgsConstructor
@Getter
@Setter
@Entity
public class PrfPost extends Auditable {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private long id;

    @Column(nullable = false)
    private String title;

    @Column(nullable = false)
    private String category;

    @Column(nullable = false, columnDefinition = "TEXT")
    private String content;

    @Column(nullable = false)
    private String tags;

    @Column(nullable = false)
    private Integer likeCount = 0;

    @OneToMany(mappedBy = "prfPost", cascade = CascadeType.REMOVE)
    @JsonBackReference
    private List<Urls> urls = new ArrayList<>();

    @ManyToOne
    @JsonManagedReference
    @JoinColumn(name = "member_id")
    private Member member;

    @OneToMany(mappedBy = "prfPost", cascade = CascadeType.REMOVE)
    @JsonBackReference
    private List<PrfPostComment> comments = new ArrayList<>();

    public void likeCountUp() {
        this.likeCount++;
    }
    public void likeCountDown() {
        this.likeCount--;
    }
}

LikeController

@PostMapping("/prf-posts/{prf-post-id}")
    public ResponseEntity postPrfPostLike(Principal principal, @PathVariable("prf-post-id") long prfPostId){
        Member member = memberService.findVerifiedMember(principal.getName());
        PrfPost prfPost = prfPostService.findverifiedPrfPost(prfPostId);

        PrfPostLike prfPostLike = likeService.addPrfPostLike(member, prfPost);

        return new ResponseEntity(new PrfPostLikeDto.Response(prfPost.getLikeCount()), HttpStatus.CREATED);
    }

LikeService

// 게시글 좋아요
public PrfPostLike addPrfPostLike(Member member, PrfPost prfPost){
        PrfPostLike prfPostLike = new PrfPostLike(member, prfPost);
        prfPost.likeCountUp();

        return prfPostLikeRepository.save(prfPostLike);
}

코드 설명

  • PrfPost Entity 클래스에 likeCount 필드를 추가
  • LikeController에 POST 요청이 들어오면, addPrfPostLike 메서드를 통해서 likeCountUp()을 통해 likeCount에 1을 더해준다.
  • prfPostLike.save()를 통해 값을 저장한다.

나의 생각

만약 id가 1인 PrfPost의 likeCount가 0이였다면, 이 과정을 겪고 나서

  • PrfPost Entity 클래스의 likeCount 필드는 값이 1이 된다.
  • prfPostLike.save()를 했으므로 PRF_POST_LIKE 테이블에 값이 insert된다.
  • PRF_POST의 LIKE_COUNT는 0으로 변함이 없을 것이라고 생각했다.
    => save를 하지 않았기 때문에 아무 변화가 없을 것이라고 예상했다!

콘솔

Hibernate: 
    insert 
    into
        prf_post_like
        (id, created_at, modified_at, member_id, prf_post_id) 
    values
        (default, ?, ?, ?, ?)
Hibernate: 
    update
        prf_post 
    set
        modified_at=?,
        category=?,
        content=?,
        like_count=?,
        member_id=?,
        tags=?,
        title=? 
    where
        id=?

위처럼 prfPostLike.save()를 했을 뿐인데 update prf_post문이 발생한 이유는 더티 체킹 때문이다.

더티 체킹

  • Dirty = 상태의 변화
  • Dirty Checking = 상태 변경 검사
  • JPA는 트랜잭션이 끝나는 시점에 변화가 있는 모든 엔티티 객체의 데이터베이스를 자동으로 반영해준다.
    • Update Query를 통해 DB를 수정해준다.
  • 변화가 있다 = 스냅샷과 다른 점이 있다.
    • JPA에서는 엔티티를 조회하면 해당 엔티티의 조회 상태를 스냅샷으로 만들어둔다!
  • @DynamicUpdate를 붙이면 엔티티 전체를 update하지 않고 변경된 필드만 update되도록 해준다.

해결

나는 더티 체킹이 일어나야하는 상황이였으므로 PrfPost Entity 클래스에 @DynamicUpdate만 붙이고 끝냈다.

[참고]
https://jojoldu.tistory.com/415
https://jojoldu.tistory.com/536


Sorting

발단

게시글 리스트를 조회할 때, 인기순/최신순 정렬이 있다.

https://www.bezkoder.com/spring-data-sort-multiple-columns/

0개의 댓글