Whiteship's Note

'@OneToMany'에 해당되는 글 1건

  1. 2007.09.22 JPA @OneToMany

JPA @OneToMany

Hibernate/Annotation : 2007.09.22 14:35


참조 : http://www.oracle.com/technology/products/ias/toplink/jpa/resources/toplink-jpa-annotations.html#OneToMany
사용자 삽입 이미지
위와 같은 관계에 있을 때 Category도 자신에 속해있는 Post를 참조할 수 있고 Post도 자신이 속한 Category를 참조할 수 있다면 Java 코드는 다음과 같이 작성할 수 있습니다.

public class Category {

    private Long categoryId;

    private String categoryName;

    private Set<Post> posts;

    ...
}

public class Post {

    private Long postId;

    private Category category;
 
    ...
}

Category 입장에서 Post를 보면 "Category 하나는 여러 Post와 연관을 맺습니다." 따라서 OneToMany 관계 입니다.

@OneToMany 애노테이션을 getter위에 붙여 줍니다.
사용자 삽입 이미지
설정 할 수 있는 속성은 위에 보이는 것과 같이 네 개가 있습니다.

cascade의 사전적인 의미는 "작은 폭포" "계단식 정보 전달" 이라는 뜻이 있습니다. 이것으로 추축할 때 어느쪽 Entity에 영향을 주면 다른 쪽 Entity에도 어떤 영향을 줄 수 있는 설정이라는 것으로 생각할 수 있습니다.

fetch의 사전적인 의미는 "가지고 오다" "자아내다" 라는 뜻이 있습니다. 즉 해당 Entity를 불러올 때 연관을 맺고 있는 상대방(OneToMany이기 때문에 상대방은 Many쪽이 되겠죠.)들을 가져오는 것과 관련된 속성이라고 생각할 수 있습니다.

mappedBy는 "누군가에 의해 관계를 맺고 있다." 즉, 누군가 한테 종속되어 있다. 라는 설정으로 생각할 수 있겠습니다.

targetEntity는 연관을 맺고 있는 타겟을 지칭하는 듯해 보입니다.

속성

설명

기본값

cascade

관계를 맺고 있는 타겟 쪽에 어떠한 persistence operation들을 연쇄적으로 적용하고 싶을 때 설정합니다.

 

ALL, MERGE, PERSIST, REFRESH, REMOVE 등의 값을 사용하여 여러 개의 cascade 속성을 설정할 수 있습니다.

 

참조무결성을 위한 설정으로 보이며, Hibernate @Cascade 를 사용하여 보다 다양한 cascade 옵션을 사용할 수 있습니다.

비어있는 CascadeType 배열

fetch

연관을 맺고 있는 Entity들을 요청하는 순간 가져오는 설정이 LAZY ,

 

해당 Entity를 가져올 때 미리 연관을 맺고 있는 Entity들까지 모두 가져오는 것이 EAGER 입니다.

FetchType.LAZY

mappedBy

관계가 양방향 일 때는 mappedBy 속성에 관계의 주인이 되는 쪽에서 어떤 속성으로 접근을 하는지 설정해 줍니다.

if the relationship is unidirectional, the persistence provider determines the field that owns the relationship.

targetEntity

만약 Generic을 사용하지 않은 Collection일 때는 이 속성을 관계의 주인이 되는 쪽 클래스로 설정해 주어야 합니다.

타입을 명시한 Collection을 사용했을 때는 해당 타입으로 사용합니다.


다시 Category와 Post의 관계로 돌아가서...

Category와 Post 관계 중에 어느 쪽이 관계의 주인이 되는지 생각해 보겠습니다. "관계의 주인" 영어 문서에는 owner side, owning entity등으로 표햔을 하고 있는데, 아무래도 직관적으로 생각해 봤을 때 DB 테이블 간의 관계를 설정할 때 상대방의 주키를 자신의 외례키로 가지는 쪽을 말하는 것 같습니다.

위의 관계라면 Post 에서 Catergory를 외례키로 가지고 있을 것이기 때문에, Post를 owning entity로 볼 수 있습니다.

그리고 Category 엔티티를 읽어 올 때 거기에 딸려 있는 모든 Post를 미리 읽어오게 하고 싶지 않습니다. 그러면 Category 목록만 보고 있는데도 그 안에 딸려 있는 모든 Post들을 DB에서 가져오게 될 텐데 그러면 엄청나게 많은 부하가 생길 것 같기 때문입니다. 그래서 fetch의 기본값인 LAZY를 사용하겠습니다.

cascade 속성은 owning entity에서 설정해주면 될 것 같고, targetEntity는 사용할 필요가 없습니다. 저는 Generic을 사용했기 때문에 별도로 명시해줄 필요가 없습니다.

위의 상황을 종합하여 다음과 같이 설정할 수 있습니다.

@OneToMany(fetch=FetchType.LAZY, mappedBy="category")

public Set<Post> getPosts() {

       if(posts == null) posts = new HashSet<Post>();

       return posts;

}


지금 예제는 양방향 관계이기 때문에 Owning Entity쪽 즉 Post 클래스의 getCategory()에 @ManyTonOne 설정을 하도록 하겠습니다. 너무 길어서 다음글로 이어집니다.

'Hibernate > Annotation' 카테고리의 다른 글

@CollectionOfElements 애노테이션  (0) 2008.09.19
Table 애노테이션  (0) 2008.06.19
JPA @Transient  (0) 2007.09.27
JPA @JoinColumn  (1) 2007.09.22
JPA @ManyToOne  (0) 2007.09.22
JPA @OneToMany  (0) 2007.09.22
top