단방향 다대다 관계

  • 대부분 추가적인 정보가 필요하기 때문에, 별도의 assiation class를 만들게 된다. 여기서는 간단한 다대다 맵핑.

Set 타입으로 맵핑하기

Category.java
@ManyToMany
@JoinTable(name = "CATEGORY_ITEM", joinColumns = @JoinColumn(name = "CATEGORY_ID"),
inverseJoinColumns = @JoinColumn(name = "ITEM_ID"))
private Set<Item> items = new HashSet<Item>();
  • 이 때는 Category 클래스에 별도의 컬럼이 생기지 않는다. @ManyToOne에서 Join Table을 만들었을 때는 inverseJoinColumns의 컬럼이 생겼었다.
  • 콜렉션에 추가할 때(category.getItems().add(itme)) 다음의 SQL 날린다. insert into CATEGORY_ITEM (CATEGORY_ID, ITEM_ID) values (?, ?)

Idbag 타입으로 맵핑하기

Category.java
@ManyToMany
@CollectionId(
columns=@Column(name="CATEGORY_ITEM_ID"),
generator = "sequence",
type = @Type(type="long")
)
@JoinTable(name = "CATEGORY_ITEM", joinColumns = @JoinColumn(name = "CATEGORY_ID"),
inverseJoinColumns = @JoinColumn(name = "ITEM_ID"))
private Set<Item> items = new HashSet<Item>();
  • surrogate 키를 가지고 있기 때문데, 중복을 허용한다.
  • @CollectionId, @Type은 하이버네이트의 애노테이션이다.
  • 콜렉션에 추가할 때 다음의 SQL 날린다. insert into CATEGORY_ITEM (CATEGORY_ID, CATEGORY_ITEM_ID, ITEM_ID) values (?, ?, ?)

List 타입으로 맵핑하기

Category.java
@ManyToMany
@JoinTable(name = "CATEGORY_ITEM", joinColumns = @JoinColumn(name = "CATEGORY_ID"),
inverseJoinColumns = @JoinColumn(name = "ITEM_ID"))
@IndexColumn(name = "DISPLAY_POSITION")
private List<Item> items = new ArrayList<Item>();
  • 콜렉션에 추가할 때 다음의 SQL 날린다. insert into CATEGORY_ITEM (CATEGORY_ID, DISPLAY_POSITION, ITEM_ID) values (?, ?, ?)

양방향 다대다 관계

Item.java
@ManyToMany(mappedBy="items")
private Set<Category> categories = new HashSet<Category>();
  • 양방향 관계에서 1쪽의 inverse로 맵핑했었던 이유? 외례키 컬럼을 두 번이나 사용했으니까.
  • 이번에도 마찬가지로, 두 쪽 중에 한 쪽은 inverse로 설정해 주어야 한다.
  • cascade 설정 중에 all, delete, delete-orphans는 다대다 관계에서 의미가 없다.
    왜? Value 타입이면 모를까, Entity 타입인데, 다른 Entity가 지워진다고 해서, 해당 Entity까지 지워지라는
    보장은 없다. 거의 그런 경우는 없을 것이다. 따라서 의미가 없다. save or update만 사용하는게 좋겠다.
  • 양방향 관계에 있는 콜렉션 타입 결정은 inverse와 관련이 있다. inverse쪽에는 bag과 set처럼
    id가 없는 것들만 올 수 있다. 왜? index나 키를 생성하는 쪽 SQL을 무시해버리면 indexColumn에 필요한 정보가
    들어갈리 없으니까. 결론적으로, 양쪽 모두 index나 키를 가지는 콜렉션끼리 다대다 관계를 가질 수 없다. 왜? 양쪽 중 한
    쪽은 inverse로 설정할 텐데 그러면 그 쪽에 필요한 정보가 생성되지 않을테니까.