일대다 양방향 (일 엔티티가 외래 키 주인)
- 이런 매핑은 공식적으로 존재X
- @ManyToOne @JoinColumn(name = "ManyEntity", insertable=false, updatable=false)
- 읽기 전용 필드를 사용해서 양방향 처럼 사용하는 방법
- 다대일 양방향을 사용하자.
일대일 [1:1]
- 일대일 관계는 반대도 일대일
- 주 테이블이나 대상 테이블 중에 외래 키 선택 가능
- 주 테이블에 외래 키
- 대상 테이블에 외래 키
- 외래 키에 데이터베이스 유니크 제약조건 추가
- 주 테이블(User)에 외래 키
- 주 객체가 대상 객체의 참조를 가지는 것 처럼 주 테이블에 외래 키를 두고 대상 테이블을 찾음
- 객체지향 개발자 선호
- JPA 매핑 편리
- 장점: 주 테이블만 조회해도 대상 테이블에 데이터가 있는지 확인 가능
- 단점: 값이 없으면 외래 키에 NULL 허용
- 대상 테이블(Locker)에 외래 키
- 대상 테이블에 외래 키가 존재
- 전통적인 데이터베이스 개발자 선호
- 장점: 주 테이블과 대상 테이블을 일대일에서 일대다 관계로 변경할 때 테이블 구조 유지
- 단점: 프록시 기능의 한계로 지연 로딩으로 설정해도 항상 즉시 로딩됨
User Entity
package jbabook.jpa.shop.domain;
import jakarta.persistence.*;
@Entity
public class User {
@Id
@GeneratedValue
@Column(name = "LOCKER_ID")
private Long id;
@Column(name = "USER_NAME")
private String name;
@OneToOne
@JoinColumn(name = "LOCKER_ID")
private Locker locker;
}
양방향
Locker Entity
package jbabook.jpa.shop.domain;
import jakarta.persistence.*;
@Entity
public class Locker {
@Id @GeneratedValue
@Column(name = "LOCKER_ID")
private Long id;
@Column(name = "LOCKER_NAME")
private String name;
@OneToOne(mappedBy = "locker")
private User user;
}
단방향
Locker Entity
package jbabook.jpa.shop.domain;
import jakarta.persistence.*;
@Entity
public class Locker {
@Id @GeneratedValue
@Column(name = "LOCKER_ID")
private Long id;
@Column(name = "LOCKER_NAME")
private String name;
private User user;
}
@OneToOne
@JoinColumn(name = "LOCKER_ID")
private User user
위코드에선 어노테이션이 빠져있는데 이런 식으로 어노테이션을 사용해주어야함.
다대다[N:M]
한계
- 편리해 보이지만 실무에서 사용X
- 연결 테이블이 단순히 연결만 하고 끝나지 않음
- 주문시간, 수량 같은 데이터가 들어올 수 있음
극복
- 중간 테이블을 만들어주어야함.
- 유저 1명당 여러 개의 Item, Item 1개를 여러 유저가 사용 = 다대다
- @ManyToMany 사용X -> @ManyToOne, @OneToMany
- PK.FK를 묶으면 나중에 유지보수할 때 귀찮은 경우가 생길 수도 있음
Item Entity
package jbabook.jpa.shop.domain;
import jakarta.persistence.*;
import java.util.List;
@Entity
public class Item {
@Id @GeneratedValue
@Column(name = "ITEM_ID")
private Long id;
private String name;
private int price;
private int stockQuantity;
@OneToMany(mappedBy = "item")
private List<UserItem> userItems;
}
User Entity
package jbabook.jpa.shop.domain;
import jakarta.persistence.*;
import java.util.List;
@Entity
public class User {
@Id
@GeneratedValue
@Column(name = "LOCKER_ID")
private Long id;
@Column(name = "USER_NAME")
private String name;
@OneToMany(mappedBy = "item")
private List<UserItem> userItems;
}
UserItem Entity
package jbabook.jpa.shop.domain;
import jakarta.persistence.*;
@Entity
public class UserItem {
@Id @GeneratedValue
@Column(name = "USER_ITEM_ID")
private Long id;
@ManyToOne
@JoinColumn(name = "USER_ID")
private User user;
@ManyToOne
@JoinColumn(name = "ITEM_ID")
private Item item;
}
'JPA' 카테고리의 다른 글
[JPA] 프록시 (0) | 2024.01.12 |
---|---|
[JPA] 상속관계 매핑 (0) | 2024.01.11 |
[JPA] 연관관계 매핑 예제 (0) | 2024.01.10 |
[JPA] 연관 관계 매핑 기초2 (양방향) (1) | 2024.01.09 |
[JPA] 연관 관계 매핑 기초1 (단방향) (1) | 2024.01.09 |