인터넷 쇼핑의 고객(Member)과 장바구니(Cart)를 가정해 보자.
고객 1명은 1개의 장바구니를 가지며, 장바구니 입장에서도 1개의 장바구니는 1명의 고객과 대응된다. 때문에 1대1 관계이다.
여기서는 Cart와 Member가 서로 조회 가능한 양방향 연결만을 다룬다.
아래는 Cart Class에 대한 코드이다.
Entity는 id와 member 객체를 갖지만,
DB에서는 id와 member_id(foreign key - int 타입)를 갖는다.
@Entity
public class Cart {
@Id
@Column(name="cart_id")
private Long id;
@OneToOne
@JoinColumn(name="member_id")
private Member member;
@Override
public String toString() {
return "Cart{" +
"id=" + id +
", member=" + member +
'}';
}
... Getter(),Setter() 생략
}
아래는 Member Class에 대한 코드이다.
Entity는 id,password,name,email,cart를 갖는다.
DB에서는 동일하게 Attribute를 가질 수 도, 혹은 cart_id만 제외할 수 도 있다.
@Entity
public class Member {
@Id
private Long id;
private String password;
private String name;
private String email;
@OneToOne(mappedBy="member")
private Cart cart
@Override
public String toString() {
return "Member{" +
"id=" + id +
", password='" + password + '\'' +
", name='" + name + '\'' +
", email='" + email + '\'' +
'}';
}
... Getter(),Setter() 생략
}
@Entity
public class Cart {
@Id
@Column(name="cart_id")
private Long id;
...
@OneToOne
@JoinColumn(name="member_id")
private Member member;
...
}
@Entity
public class Member {
@Id
private Long id;
...
@OneToOne(mappedBy="member")
private Cart cart
...
}
- Entity간에는 서로 참조가 가능하지만(Cart <-> Member), Table상에서는 Cart의 FK로 member_id를 갖는다.
- Cart에 Member 객체를 주입하기만 해도, Member는 Cart객체를 다룰 수 있다.
cart.setMember(member); member.getCart(); // ok
- 반대로
member.setCart(cart);
만 하면 Error 발생
- mappedBy는 연관 관계의 주인을 지정하는 데 사용된다. (주인 - Member)
- mappedBy에는 FK를 가져오는 클래스(Cart)의 필드(변수) 이름(member)을 적어준다.
@Entity
public class Cart {
@Id
@Column(name="cart_id")
private Long id;
...
@OneToOne
@JoinColumn(name="member_id")
private Member member;
...
}
@Entity
public class Member {
@Id
private Long id;
...
@OneToOne
@JoinColumn(name="cart_id")
private Cart cart
...
}
- Entity간에는 서로 참조가 가능하며(Cart <-> Member), Table상에서도 Cart의 FK로 member_id를, Memeber의 FK로 cart_id를 갖는다.
- 반드시 두 객체가 서로를 주입해야 한다.
cart.setMember(member); member.setCart(cart);
- Member 클래스의 cart에도 @OneToOne 이 붙었기 때문에, 기본적으로 Member Table에 cart에 대한 Foreign Key(FK) Attribute자리가 생성된다.
@OneToOne private Cart cart
... cart_id ... aaa@aaa null
- 그러나, mappedBy 속성을 적어주면 FK가 생성되지 않는다.
@OneToOne(mappedBy="member") private Cart cart
... ... aaa@aaa
- 즉, @OneToOne이 붙어있다면, Table에 FK 자리가 생성된다.
- 양방향 연결시 toString()에서 Entity가 서로 참조하여 StackOver Flow가 발생함 수 있으므로 주의하자.