[JPA] 일대다 다대일 연관관계 @OneToMany, @ManyToOne

jpa, spring

일대다? 다대다? #

1:N #

N:N #

image


1:N / N:1 연관관계 알아보기 #

@Entity
@Table(name="CART")
public class Cart {
    //...     

    @OneToMany(mappedBy="cart")
    private Set<Items> items;
    //...
}
@Entity
@Table(name="ITEMS")
public class Items {

    //...
    @ManyToOne
    @JoinColumn(name="cart_id", nullable=false)
    private Cart cart;

    public Items() {}

    // getters and setters
}

연관관계의 주인 #

잘못된 시나리오 테스트 환경을 구현해본다.

Cart cart1 = new Cart();
Cart cart2 = new Cart();

Items item1 = new Items(cart1);
Items item2 = new Items(cart2); 

Set<Items> itemsSet = new HashSet<Items>();
itemsSet.add(item1);
itemsSet.add(item2); 
cart1.setItems(itemsSet); // wrong!

이는 관계의 주인을 정함으로써 해결한다. 관계의 주인 측에 속하는 참조가 우선 적용되어 DB에 저장되게 된다.

이제 위의 테스트 시나리오로 돌아가면, item2가 연관관계의 주인이기 때문에 item2의 참조를 DB에 저장한다.

그러므로 위의 테스트 시나리오의 결과는 아래와 같다.

item1 ID=1, Foreign Key Cart ID=1
item2 ID=2, Foreign Key Cart ID=2

option #

optiondescriptiondefault
optionalfalse 로 설정하면 연관된 엔티티가 항상 있어야 한다.false
fetch글로벌 fetch 전략을 설정한다@ManyToOne=FetchType.EAGER / @OneToMany=FetchType.LAZY
cascade영속성 전이 기능을 사용한다. 
targetEntity연관된 엔티티의 타입 정보를 설정한다. 이 기능은 거의 사용하지 않는다. 컬렉션을 사용해도 제네릭으로 타입 정보를 알 수 있다. 

양방향 매핑시 가장 많이 하는 실수 #

일반적으로 엔티티를 사용하지 않고 DTO 로 변환해서 사용하는 것이 매우 매우 매우 권장된다.

설계시에는 단방향 매핑만으로 끝내고, 역방향으로 참조해야 되는 경우만 양방향 매핑을 추가하는것을 권장한다.


참고 #