[JPA] 일대일 관계

지인·2023년 6월 26일
0

Spring

목록 보기
9/20

🐰 1 대 1 관계 - @OneToOne

🐾 일대일 관계는 그 반대도 일대일이다.

🐾 주 테이블이나 대상 테이블 중에 외래 키를 넣을 테이블을 선택 가능하다.

🐾 외래 키에 데이터베이스 유니크 제약조건이 추가되어야 일대일 관계가 된다.

  • 1 대 1 관계를 맺어주는 역할

  • 고객 Entity와 음식 Entity가 1 대 1 관계라 가정하여 관계를 설명하려고 한다.


👉🏻 단방향 관계

🐾 다대일[N:1] 단방향 관계 매핑과 JPA 어노테이션만 달라지고, 거의 유사하다.

  • Entity에서 외래 키의 주인은 일반적으로 N(다)의 관계인 Entity 이지만 1 대 1 관계에서는 외래 키의 주인을 직접 지정해야 한다.

    • 외래 키 주인만이 외래 키를 등록, 수정, 삭제할 수 있으며, 주인이 아닌 쪽은 오직 외래 키를 읽기만 가능하다.
    • @JoinColumn()은 외래 키의 주인이 활용하는 애너테이션이다.
  • 외래 키의 주인만 상대 Entity 타입의 필드를 가지면서 @JoinColumn()을 활용하여 외래 키의 속성을 설정한다.


음식 Entity가 외래 키의 주인인 경우

  • 음식
            @Entity
            @Table(name = "food")
            public class Food {
                @Id
                @GeneratedValue(strategy = GenerationType.IDENTITY)
                private Long id;
                private String name;
                private double price;

                @OneToOne
                @JoinColumn(name = "user_id")
                private User user;
            }
  • 고객
            @Entity
            @Table(name = "users")
            public class User {
                @Id
                @GeneratedValue(strategy = GenerationType.IDENTITY)
                private Long id;
                private String name;
            }

고객 Entity가 외래 키의 주인인 경우!

  • 음식
            @Entity
            @Table(name = "food")
            public class Food {
                @Id
                @GeneratedValue(strategy = GenerationType.IDENTITY)
                private Long id;
                private String name;
                private double price;
            }
  • 고객
            @Entity
            @Table(name = "users")
            public class User {
                @Id
                @GeneratedValue(strategy = GenerationType.IDENTITY)
                private Long id;
                private String name;

                @OneToOne
                @JoinColumn(name = "food_id")
                private Food food;
            }



👉🏻 양방향 관계

⚠️ 주의!
1. 외래 키의 주인 Entity에서 @JoinColumn() 애너테이션을 사용하지 않아도 default 옵션이 적용되기 때문에 생략이 가능하다.
- 다만 1 대 N 관계에서 외래 키의 주인 Entity가 @JoinColumn() 애너테이션을 생략한다면 JPA가 외래 키를 저장할 컬럼을 파악할 수가 없어서 의도하지 않은 중간 테이블이 생성된다.
- 따라서 외래 키의 주인 Entity에서 @JoinColumn() 애너테이션을 활용하시는게 좋다.

2. 양방향 관계에서 mappedBy 옵션을 생략할 경우 JPA가 외래 키의 주인 Entity를 파악할 수가 없어 의도하지 않은 중간 테이블이 생성되기 때문에 반드시 설정해주시는게 좋다.

🐾 다대일[N:1] 양방향 매핑 처럼 외래키가 있는 곳이 연관관계의 주인이다.

  • 양방향 관계에서 외래 키의 주인을 지정해 줄 때 mappedBy 옵션을 사용한다.

    • mappedBy의 속성값은 외래 키의 주인인 상대 Entity의 필드명을 의미한다.
  • 외래 키의 주인은 상대 Entity 타입의 필드를 가지면서 @JoinColumn()을 활용하여 외래 키의 속성을 설정해준다.


음식 Entity가 외래 키의 주인인 경우!

  • 음식
@Entity
@Table(name = "food")
public class Food {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;
    private double price;

    @OneToOne
    @JoinColumn(name = "user_id")
    private User user;
}
  • 고객
@Entity
@Table(name = "users")
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;

    @OneToOne(mappedBy = "user")
    private Food food;
}

고객 Entity가 외래 키의 주인인 경우!

  • 음식
@Entity
@Table(name = "food")
public class Food {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;
    private double price;

    @OneToOne(mappedBy = "food")
    private User user;
}
  • 고객
@Entity
@Table(name = "users")
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;

    @OneToOne
    @JoinColumn(name = "food_id")
    private Food food;
}
profile
열쩡

0개의 댓글