자바 ORM 표준 JPA 프로그래밍
http://www.kyobobook.co.kr/product/detailViewKor.laf?mallGb=KOR&ejkGb=KOR&barcode=9788960777330
public void setTeam(Team team) {
this.team = team;
if(!team.getMembers().contains(this)){
team.getMembers().add(this);
}
}
208p의 이거 이미 팀이 있는데 변경하는 경우 기존 팀에서 삭제를 하지 않는거 같은디????????????
이러한 편의 메서드는 한 곳에만 작성할 때는 괜찮지만 양쪽에 작성한다면 무한루프에 빠지지 않도록 검사하는 로직이 있어야한다.
일대다에서는 다가 외래 키를 가지고 있는데 일대다 단방향 관계를 반대쪽 테이블인 일에서 외래 키를 관리한다.
일대다 단방향 관계를 매핑할 때는 @JoinColumn 을 명시해야 한다.
그렇지 않으면 JPA는 연결 테이블을 중간에 두고 연관관계를 관리하는 조인 테이블 전략을 기본으로 사용해서 매핑한다.
이 관계에서는 연관관계를 처리하기 위해서 UPDATE SQL을 추가로 실행해야한다.
웬만하면 일대다 단방향 대신에 다대일 양방향을 사용하자
굳이 하려면 가능하지만 이것 역시 다대일 양방향 관계를 사용하자.
일대다 단방향에 반대편에 다대일 단방향 매핑을 읽기전용으로 하면 가능하긴 하다.
일대일 관계는 외래 키가 어느쪽이든 가질 수 있다.
외래 키를 객체 참조와 비슷하게 사용할 수 있다.
주 테이블이 외래 키를 가지고 있으므로 주 테이블만 확인해도 대상 테이블과 연관관계가 있는지 알 수 있다.
테이블 관계를 일대일에서 일대다로 변경할 때 테이블 구조를 그대로 유지할 수 있다.
이 경우 단방향 관계는 JPA에서 지원하지 않고 매핑할 수 있는 방법도 없다.
따라서 양방향 관계로 해야한다.
프록시를 사용할 때 외래 키를 직접 관리하지 않는 일대일 관계는 지연 로딩으로 설정해도 즉시 로딩된다.
프록시 대신에 bytecode instrumentation을 사용하면 해결할 수 있다.
관계형 데이터베이스는 정규화된 테이블 2개로 다대다 관계를 표현할 수 없다.
중간에 연결 테이블을 추가해야한다.
객체는 테이블과 다르게 다대다 관계를 만들 수 있다.
@ManyToMany와 @JoinTable을 사용해서 연결 테이블을 바로 매핑하면 된다.
@ManyToMany를 사용하면 연결 테이블을 자동으로 처리해주므로 도메인 모델이 단순해지고 편리하다.
실무에서는 연결 테이블에 추가적인 데이터를 저장할 필요가 있을 수 있다.
이 경우에는 연결 엔티티를 생성하여 두 테이블과 연결 엔티티를 일대다로 매핑해주면된다.
연결 엔티티에서는 기본 키 대신 외래 키 두개에 @Id를 사용해서 기본 키 + 외래 키를 한번에 매핑하고 @IdClass를 사용해서 복합 기본 키를 매핑할 수 있다.
JPA에서 복합 기본 키를 사용하려면 별도의 식별자 클래스를 만들고 @IdClass로 식별자 클래스를 지정하면 된다.
복합 기본 키를 위한 식별자 클래스는
1. Serializable을 구현해야한다.
2. equals와 hashCode 메서드를 구현해야한다. (자바 IDE에는 대부분 이 둘을 자동 생성해주는 기능이 있다.)
3. 기본 생성자가 있어야한다.
4. 식별자 클래스는 public 이어야 한다.
5. @IdClass 사용하는 방법 외에 @EmbeddedId를 사용하는 방법도 있다.
부모 테이블의 기본 키를 받아서 자신의 기본 키 + 외래 키로 사용하는 것을 식별 관계라 한다.
데이터베이스에서 자동으로 생성해주는 대리 키를 기본 키로 사용하는 것이다.
간편하고 거의 영구히 쓸 수 있으며 비즈니스에 의존하지 않는다.
복합 키를 만들지 않아도 되므로 간단하게 매핑 가능하다.