@CollectionOfElements 애노테이션

참조
http://www.hibernate.org/hib_docs/annotations/api/org/hibernate/annotations/CollectionOfElements.html

Entity 타입 콜렉션 말고 Value 타입 콜렉션을 맵핑할 때 사용하는 애노테이션 입니다.

    @CollectionOfElements
    private List<Integer> hobbies;

간단하죠. JPA는 아니고 하이버네이트 애노테이션입니다. fetch와 targetClass 속성을 가지고 있는데, targetClass는 콜렉션 타입을 명시하지 않았을 때 사용하면 됩니다.

Table 애노테이션

패키지: javax.persistence

라이브러리: persistence-api-1.0.jar

속성:
– catalog: 테이블의 카탈로그
– name: 테이블 이름. 기본값은 entity 이름
– schema: 테이블의 스키마
– uniqueConstraints: Unique 제약을 걸 컬럼 설정.

예제

@Table(uniqueConstraints = @UniqueConstraint(columnNames = { “date”, “item_id”, “bay_id” }))
pubic class Inv { … }

JPA @Transient

@Entity 애노테이션이 붙은 클래스의 모든 속성들은 기본으로 모두 테이블의 필드로 생성하게 됩니다. 만약 어떤 속성을 테이블의 필드로 만들고 싶지 않다면, @Transient 애노테이션을 해당 속성 또는 해당 속성의 getter위에 붙여주면 됩니다.

@Entity
public class Member {
    private Long memberId;
    private String password;
    @Transient
    private String confirmPassword;
    …
}

회원가입을 할 때 확인하는 패스워드의 경우 제대로 입력했는지 확인하기 위해서 한 번 더 입력을 하는데, 이러한 속성은 DB에 저장할 필요가 없기 때문에, @Transient로 설정해 줄 수 있습니다.

JPA @JoinColumn

참조 :http://www.oracle.com/technology/products/ias/toplink/jpa/resources/toplink-jpa-annotations.html#JoinColumn
링크에 내용이 상당히 많아서 정리는 나중에 하기로 하고…

사용자 삽입 이미지
이름이 암시 하듯이 Join 컬럼 설정을 할 때 사용합니다. 위의 관계에서 Post에 Catergory 의 주키를 외례키로 가짐으로써 Join을 하고 있으니… Post Entity의 getCategory()에 @JoinColumn을 붙여 줍니다.

그러면 Post 테이블을 만들 때 join column 이름을 기본으로 Entity 명 + 언더바 + 주키 를 사용합니다.

public class Category {

    private Long categoryId;

    ..
}

현재 Category 클래스가 위와 같기 때문에 외례키(join column)이 categoty_categoryId 와 같은 형태로 생기게 됩니다. 별로 멋진 이름은 아닌 것 같으니 다음과 같이 설정해 줍니다.

    @ManyToOne(fetch=FetchType.LAZY, optional=false)
    @JoinColumn(name=”categoryId”)
    public Category getCategory() {
        return category;
    }

그리고  이전 글에서 잠시 고민했었던 cascading 설정은 Category를 지우면 해당 Categorry에 모든 Post마저 삭제 되도록 Category에 설정해 주겠습니다. 이밖에도 모든 cascading을 적용하도록 아예 all로 하겠습니다.

    @OneToMany(fetch = FetchType.LAZY, mappedBy = “category”, cascade = { CascadeType.ALL })
    public Set<Post> getPosts() {
        if (posts == null)
            posts = new HashSet<Post>();
        return posts;
    }

자 이제 설정은 마쳤고 제대로 설정을 한 건지, 원하는 대로 동작 하는지 테스트를 해봐야겠습니다.

JPA @ManyToOne

참조 : http://www.oracle.com/technology/products/ias/toplink/jpa/resources/toplink-jpa-annotations.html#ManyToOne
사용자 삽입 이미지
자 이번에는 Post쪽에서 생각해 보겠습니다. “하나의 Post는 하나의 Category와 연관을 맺고 있습니다.” 그럼 1:1 인가요? ㅋㅋ 아니죠. “또 다른 하나의  Post가 위의 Post가 연관을 맺고 있는 Category와 연관을 맺을 수 있습니다.” 따라서 다:1 즉 ManyToOne의 관계이 있습니다.

사용자 삽입 이미지
@ManyToOne에 설정할 수 있는 속성들은 위와 같습니다. 이 중에서 세 개는 이미 @OneToMany에서 살펴보았고, 새로운 것은 딱 하나 optional 이 있습니다.

optional 은 “부가적인”, “임의의”란 뜻으로 해당 속성이 임의적으로 있을 수도 있고, 없을 수도 있는지를 설정하는 것 같습니다.























속성


설명


기본값


cascade


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


 


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


 


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


비어있는 CascadeType 배열


fetch


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


 


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


FetchType.LAZY


optinal


해당 속성 또는 필드에 빈 값(null)이 들어갈 수 있는지 여부를 나타냅니다.


 


반드시 값이 필요하다면, true로 설정합니다.


true


targetEntity


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


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


다시 예제로 돌아가서 Post가 owning entity인데, 이 녀석을 삭제하거나, 변경한다고 해서, Category도 삭제되거나 변경되어야 하지는 않아도 될 것 같습니다. 흠.. 오히려 Category를 삭제하면 Post들이 모두 삭제 되어야 할 것 같은데 그러면 Cattegory에서 cascade 속성을 설정해야 하나;; 흠…

Post 객체를 불러올 때 Post와 연관을 맺고 있는 Category도 가져와야 할 필요는 없어 보입니다.

Post는 꼭 어느 Category엔가에는 들어야 할 것이기 때문에 외례키가 null일 경우는 없을 것 같습니다.

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



@ManyToOne(fetch=FetchType.LAZY, optional=false)


public Category getCategory() {


       return category;


}


여기서 이만 끝나면 좋겠지만, 아직 끝나지 않았습니다. @JoinColumn 이라는 녀석을 붙여줘야 합니다. 다음 글에서 살펴보겠습니다.