복합키 - 일대일 관계

PPakSSam·2022년 1월 13일
0

복합키 목차


일대일 관계

위와 같이 Post클래스PostDetails클래스가 있다고 하자.

  • @MapsId를 활용하지 않은 1:1 매핑
  • @MapsId를 활용한 1:1 매핑

이 2가지에 대해 설명하고자 한다.

@MapsId를 활용하지 않은 매핑


[PostDetails]

@Entity(name = "PostDetails")
@Table(name = "post_details")
public class PostDetails {
 
    @Id
    @GeneratedValue
    private Long id;
 
    @Column(name = "created_on")
    private Date createdOn;
 
    @Column(name = "created_by")
    private String createdBy;
 
    @OneToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "post_id")
    private Post post;
 
    public PostDetails() {}
 
    public PostDetails(String createdBy) {
        createdOn = new Date();
        this.createdBy = createdBy;
    }
 
    //Getters and setters omitted for brevity
}

[Post]

@Entity(name = "Post")
@Table(name = "post")
public class Post {
 
    @Id
    @GeneratedValue
    private Long id;
 
    private String title;
 
    @OneToOne(mappedBy = "post", cascade = CascadeType.ALL,
              fetch = FetchType.LAZY, optional = false)
    private PostDetails details;
 
    //Getters and setters omitted for brevity
 
    public void setDetails(PostDetails details) {
        if (details == null) {
            if (this.details != null) {
                this.details.setPost(null);
            }
        }
        else {
            details.setPost(this);
        }
        this.details = details;
    }
}

위의 코드처럼 매핑을 한 경우 DB에서는 다음과 같이 테이블이 생성된다.

여기서 효율적이지 않음을 느껴야 하는데 왜냐하면 어차피 1:1 관계이므로
post테이블의 PK와 post_details의 PK가 서로 미러링하도록 하는 것이 더 좋기 때문이다.

그래서 테이블이 다음과 같이 설계가 되어야 효율적일 것이다.

이렇게 하면 post_details의 PK가 FK도 되며 두 테이블의 PK를 공유하게 된다.
그렇다면 위의 테이블처럼 설계되었을 때 어떻게 매핑을 해야할까?
바로 이것이 @MapsId를 활용한 1:1 매핑이다.

@MapsId를 활용한 매핑


[PostDetails] -> [Post]는 위의 코드와 같다.

@Entity(name = "PostDetails")
@Table(name = "post_details")
public class PostDetails {
 
    @Id
    private Long id;
 
    @Column(name = "created_on")
    private Date createdOn;
 
    @Column(name = "created_by")
    private String createdBy;
 
    @OneToOne(fetch = FetchType.LAZY)
    @MapsId
    private Post post;
 
    public PostDetails() {}
 
    public PostDetails(String createdBy) {
        createdOn = new Date();
        this.createdBy = createdBy;
    }
 
    //Getters and setters omitted for brevity
}
  • @MapsId를 추가함으로써 Post의 id와 PostDetails의 id가 미러링된다.
    -> 어차피 Post의 id 값을 가져오므로 @GeneratedValue가 필요없어지게 된다.

  • @MapsId를 추가함으로써 FK가 PK의 역할을 하게된다.

profile
성장에 대한 경험을 공유하고픈 자발적 경험주의자

0개의 댓글