[JPA] @OneToMany의 기본 매핑전략: JoinTable

가영·2021년 9월 21일
0

댓글(Comment)와 댓글 좋아요(CommentLike)

댓글에 좋아요를 할 수 있는 게시판을 구현하는 중이었습니다!
다른 모든 엔티티들과 함께 댓글과 댓글좋아요 엔티티도 구현을 해보았어요.

제가 생각한 댓글과 댓글 좋아요의 관계는 일대다 입니다.
댓글이 주인인 관계죠!
그래서 좋아요 table에만 foreign key가 있는 형태로 구현할 수 있어요.

어노테이션에 따로 옵션을 주지 않았다

// Comment.kt

@Entity
class Comment (
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    val id: Long,
    
    // ...
        ) {
        
    @OneToMany // no options
    val likes: MutableList<CommentLike> = ArrayList()

    // ...
}
@Entity
class CommentLike(
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    val id: Long,

    // ...
    
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "comment_id", nullable = false)
    val comment: Comment
)

Join table이 생겼네

일대다 관계에서는 당연히 테이블을 만들지 않기 때문에? (당연한 건 아닐 수도 있지만 댓글 좋아요의 경우, 제가 생각했을 때는 그랬습니다)
그랬더니 만들지도 않았던 join 테이블이 생성되더군요 흐흐..😃

그래서 @OneToMany가 어떻게 동작하는지부터 찾아보기로했습니다

mappedBy 옵션이 필요한 이유

테이블은 외래 키 하나로 두 테이블의 연관관계를 관리한다. ... 엔티티를 양방향 연관관계로 설정하면 객체의 참조는 둘인데 외래 키는 하나다. 따라서 둘 사이에 차이가 발생한다. ... 두 객체 연관관계 중 하나를 정해서 테이블의 외래키를 관리해야하는데 이것을 연관관계의 주인이라 한다.
- 자바 ORM 표준 JPA 프로그래밍 (김영한)

위의 내용을 보면 어떤 문제가 일어났었는지 알 수 있어요.

내가 객체들끼리의 참조를 두 개를 만들었고, Comment에서 @OneToMMany의 매핑방법을 명시하지 않았기 때문에 jpa가 Comment 객체에 CommentLike를 매핑하는 방식으로, 기본 전략인 JoinTable을 사용한 것입니다.
그래서 제가 원하지 않았던 매핑 테이블인 Comment_likes 가 생겼던 것이었어요.

해결

// Comment.kt

@Entity
class Comment (
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    val id: Long,
    
    // ...
        ) {
        
    @OneToMany(mappedBy = "comment")
    val likes: MutableList<CommentLike> = ArrayList()

    // ...
}

Comment 엔티티를 정의할 때, likes를 매핑하는 @OneToMany가 참조하는 외래키를 다른 엔티티(CommentLike)가 관리하는 것이라고 알려주면 됩니다!

그럼 이렇게 테이블이 사라져요 😃

끄읏


참고한 블로그입니다📝 감사합니다!

참고한 책입니다📚 감사합니다!

  • 자바 ORM 표준 JPA 프로그래밍 - 김영한

0개의 댓글