객체와 관계형 데이터베이스 테이블이 어떻게 매핑되는지 이해하는 것이다.
객체지향 프로그래밍과 데이터베이스 사이의 패러다임 불일치를 해결하는 것이 JPA의 목적과 직접적으로 연관되어 있기 때문이다.
객체 지향 프로그래밍과 관계형 데이터베이스 사이의 데이터 표현 방식이 달라서 생겨나는 문제이다.
즉, 객체지향에서는 추상화, 상속, 다형성 같은 개념이 있지만, 데이터베이스에서는 추상화, 상속, 다형성 같은 개념들이 없기 때문에 서로가 지향하는 목적이 다르므로 패러다임 불일치 문제라고 한다.
객체는 참조용 필드가 있는 객체만 다른 객체를 참조하는 것이 가능하다.
때문에, 두 객체 사이에 하나의 객체만 참조용 필드를 가지고 참고하게 되면 단방향 관계이고,
두 객체 모두가 각각 참조형 필드를 가지고 참조하면 양방향 관계이다.
JPA를 사용하여 패러다임을 맞춰주기 위해서 객체는 단방향 연관 관계를 가질지, 양방향 연관 관계를 가질지 선택해줘야 한다.
두 객체가 연관 관계를 맺으면 연관 관계의 주인을 정해야 하는데,
두 단반향 관계 중에서 제어의 권한을 갖는 실질적인 관계가 어떤 것인지 JPA에게 알려주는 것이다.
외래 키가 있는 곳이 연관 관계의 주인이다!
다중성은 데이터베이스를 기준으로 결정하며 연관관계는 대칭성을 가진다.
@Entity
public class Member {
@Id @GeneratedValue
@Column(name = "MEMBER_ID")
private Long id;
private String username;
@ManyToOne
@JoinColumn(name = "TEAM_ID")
private Team team;
...
}
@Entity
public class Team {
@Id @GeneratedValue
@Column(name = "TEAM_ID")
private Long id;
private String name;
...
}
@Entity
public class Member {
@Id @GeneratedValue
@Column(name = "MEMBER_ID")
private Long id;
private String username;
...
}
@Entity
public class Team {
@Id @GeneratedValue
@Column(name = "TEAM_ID")
private Long id;
private String name;
@OneToMany
@JoinColumn(name = "TEAM_ID")
private List<Member> members = new ArrayList<>();
...
}
@Entity
public class Member {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "MEMBER_ID")
private Long id;
private String username;
@OneToOne
@JoinColumn(name = "LOCKER_ID")
private Locker locker;
}
@Entity
public class Locker {
@Id @GeneratedValue
@Column(name = "LOCKER_ID")
private Long id;
private String name;
}
두 테이블을 연결하는 연결 테이블을 만들고, 그것을 연결 엔티티로 승격시켜줍니다.
즉 @ManyToMany -> @OneToMany와 @ManyToOne으로 나눠지는 것입니다.
Member와 Product의 다대다 관계를 Order 엔티티를 추가하며 1대다, 다대1 관계로 풀어냄