berryberrybin / board-project

0 stars 0 forks source link

Entity annotation #10

Open berryberrybin opened 1 year ago

berryberrybin commented 1 year ago
// Comment.java
@Getter
@Entity
@SQLDelete(sql = "UPDATE comment SET is_deleted=true WHERE comment_id = ?")
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class Comment extends DateTimeEntity {

    @Id
    @GeneratedValue(generator = "UUID")
    @Column(name = "comment_id", columnDefinition = "BINARY(16)")
    @GenericGenerator(name = "UUID", strategy = "org.hibernate.id.UUIDGenerator")
    private UUID id;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "post_id")
    private Post post;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "user_id")
    private User user;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "parent_Comment_id")
    private Comment parentComment;

    @OneToMany(mappedBy = "parentComment", orphanRemoval = true)
    private List<Comment> childComments = new ArrayList<>();

    @Column
    private String description;

    @Column
    private Boolean isDeleted = false;

    @OneToMany(mappedBy = "comment", cascade = CascadeType.ALL, orphanRemoval = true)
    private Set<CommentLike> commentLikes = new HashSet<>();

    @Builder
    public Comment(User user, Post post, String description, Comment parentComment) {
        this.user = user;
        this.post = post;
        this.description = description;
        this.parentComment = parentComment;
    }

    public Integer getCommentLikeCount() {
        return commentLikes.size();
    }

    public void blindDescription(String description) {
        this.description = description;
    }

    public void addCommentLike(CommentLike commentLike) {
        this.commentLikes.add(commentLike);
    }

    public void cancelCommentLike(CommentLike commentLike) {
        this.commentLikes.remove(commentLike);
    }

}
berryberrybin commented 1 year ago

CascadeType.Remove 와 orphanRemoval = true

EX) 예시

// Member.java @Entity public class Member {

@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

private String name;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn
private Team team;

public Member() {
}

}

### CascadeType.Remove로 변경하여 test할 경우 
- (1) 부모 엔티티 삭제하는 경우 
   - delete 쿼리가 3번 나감
   - 즉, Team(부모)가 삭제될때 Member(자식)도 영속성 전이 옵션으로 인해 함께 삭제됨 
- (2) 부모 엔티티에서 자식 엔티티를 제거하는 경우
   - delete쿼리가  전혀 나가지 않음
   - 영속성 전이 삭제 옵션은 부모와 자식의 관계가 끊어졌다 해서 자식을 삭제하지 않기 때문

```java
// Team.java에서 CascadeType.All 옵션 추가
@OneToMany(
        mappedBy = "team",
        fetch = FetchType.LAZY,
        cascade = CascadeType.ALL   // { CascadeType.PERSIST, CascadeType.REMOVE }와 동일하다.
    )
    private List<Member> members = new ArrayList<>();
// 부모 엔티티 삭제하는 경우 test
@Test
void cascadeType_Remove_InCaseOfTeamRemoval() {
    // given
    Member member1 = new Member();
    Member member2 = new Member();

    Team team = new Team();

    team.addMember(member1);
    team.addMember(member2);

    teamRepository.save(team);

    // when = 부모 엔티티를 삭제하는 경우, delete쿼리 3번 나감
    teamRepository.delete(team);

    // then
    List<Team> teams = teamRepository.findAll();
    List<Member> members = memberRepository.findAll();

    assertThat(teams).hasSize(0);
    assertThat(members).hasSize(0);
}
// when - 부모 엔티티에서 자식 엔티티를 제거하는 경우 test, delete쿼리가 전혀 나가지 않음
    team.getMembers().remove(0);

OrphanRemoval=true와 CascadeType.Remove를 함께 사용하는 것으로 변경해 test할 경우

// when - 부모 엔티티를 삭제하는 경우, delete쿼리 3번 나감
    teamRepository.delete(team);
  // when -부모 엔티티에서 자식 엔티티를 제거하는 경우 test, delete쿼리가 1개 나감
    team.getMembers().remove(0);