JPA

[JPA] 일대다 양방향에서 '다'엔티티에 @JoinColumn을 생략하면 안되는 이유

23 2023. 9. 22. 20:07

(우선 일대다 양방향은 잘 쓰지 않는다)
 
일대다 양방향을 공부하던 도중, 다 방향에 있는 엔티티에 @ManyToOne만 달아도 연관관계 된 객체를 알 수 있는데
왜 @JoinColumn(name = "~~", insertable=false, updatable = false)을 넣어야 되는지 궁금해졌다.
 
그래서 @ManyToOne만 달아보았다.
 
예제는 post와 comment이다. 
 
post.java

@Entity
public class Post {

    @Id
    @GeneratedValue
    private Long id;

    @OneToMany
    @JoinColumn(name = "POST_ID")
    private List<Comment> comments = new ArrayList<>();
    
    //...
}

 
comment.java

@Entity
public class Comment {

    @Id
    @GeneratedValue
    private Long id;

    private String name;

    @ManyToOne
    private Post post;
    
    // ...
    
    public void setPost(Post post) {
        this.post = post;
    }
    
    // ...
}

 

tx.begin();


Post post = new Post();
em.persist(post);

Comment commentA = new Comment();
commentA.setName("댓글 A");
Comment commentB = new Comment();
commentB.setName("댓글 B");
em.persist(commentA);
em.persist(commentB);

commentB.setPost(post);   // comment(다)에서 post(일)을 set!!

em.flush();
em.clear();

Comment findCommentB = em.find(Comment.class, commentB.getId());
Post findPost = findCommentB.getPost();
System.out.println(findPost);

tx.commit();

결과를 보니 Comment 테이블에 post_id(외래키) 필드에 값이 잘 들어왔다. 이러면 안되는 것이다.
일대다 매핑을 하였기 때문에 일대다에서 일을 맡은 post에게 외래키를 매핑할 수 있는 권한을 주었고, 
comment에게는 외래키를 매핑할 권한을 주지 않은 것을 의도하였다.
하지만 comment에서 post를 set을 했더니 외래키가 예기치 못하게 정상적으로 값이 들어왔다.
 
다시 생각해보니 @ManyToOne이 있는 필드에 @JoinColumn이 없으면 자동으로 필드명 + _ 참조객체의 식별자 로 외래키 매핑을 한다는 것을 잊고 있었다.

따라서 일대다 관계에서 양방향을 하고 싶다면 (자동으로 외래키를 매핑하게 하지 않고) insert와 update가 안되도록 옵션을 단 @JoinColumn을 만들어야 한다!!