1) 식별관계 vs 비식별 관계
- 식별관계 : 부모 테이블의 기본 키를 내려 받아서 자식 테이블의 기본 키 + 외래 키로 사용하는 관계
- 비식별관계: 부모 테이블의 기본 키를 받아서 자식테이블의 외래 키로만 사용하는 관계
- 필수적 비식별 관계 : 외래 키에 NULL 을 허용하지 않음
- 선택적 비식별 관계 : 외래 키에 NULL 을 허용
2) 복합 키 : 비식별 관계 매핑
기본 키를 구성하는 컬럼이 하나일 때
@Entity
public class Hellod {
@Id
private String id;
}
복합키 일때
-> JPA는 @IdClass와 @EmbeddedId 2가지 방법 제공
@IdClass
부모클래스
@Entity
@IdClass(ParentId.class)
public class Parent {
@Id
@Column(name ="PARENT_ID1")
private String id1; // ParentId.id1과 연결
@Id
@Column(name = "PARENT_ID1")
private String id2; // ParentId.id2와 연결
private String name;
...
}
식별자클래스
public class ParentId implements Serializable{
private String id1; // Parent.id1 매핑
private String id2; // Parent.id2 매핑
public ParentId(){
}
public ParentId(String id1, String id2){
this.id1 = id1;
this.id2 = id2;
}
@Override
public boolean equals (Object o) {...}
@Override
publid int hashCode() {...}
@IdClass 를 사용할 때 식별자 클래스가 만족해야할 조건
- 식별자 클래스의 속성명과 엔티티에서 사용하는 식별자의 속성명이 같아야한다.
- 예제의 Parent.id1 과 ParentId.id1 - Serializable 인터페이스를 구현해야한다.
- 기본 생성자가 있어야 한다.
- 식별자 클래스는 public이어야 한다.
복합키를 사용하는 엔티티 저장 하기
Parent parent = new Parent();
parent.setId1("myId1"); // 식별자
parent.setId2("myid2") // 식별자
parent.setName("parentName");
em.persist(parent);
복합키를 사용하는 엔티티 조회하기
ParentId parentId = new ParentId("myId1","myId2");
Parent parent = em.find(Parent.class, parentId);
자식클래스 예제
@Entity
public class Child{
@Id
private String id;
@ManyToOne
@JoinColumns({
@JoinColumn (name = "PARENT_ID1",
referencedColumnName = "PARENT_ID1"),
@JoinColumn (name = "PARENT_ID2",
referencedColumnName = "PARENT_ID2")
})
private Parent parent;
private String name;
}
부모 테이블의 기본 키 컬럼이 복합 키이므로 자식 테이블의 외래키도 복합 키다.
여러컬럼을 매핑해야 하므로 @JoinColumns 어노테이션을 사용하고 가각의 외래 키 컬럼을 @JoinColumn으로 매핑한다.
@EmbeddedId
@IdClass가 데이터 베이스에 맞춘 방법이라면 @EmbeddedId는 좀 더 객체지향적인 방법
@Entity
public class Parent{
@EmbeddedId
private ParentId id;
private String name;
...
}
Parent 엔티티에서 식별자 클래스를 직접 사용하고 @EmbeddedId 어노테이션을 적어주면 된다.
@Embeddable
public class ParentEd implements Serializable{
@Column (name = "PARENT_ID1")
private String id1;
@Column (name= "PARENT_ID2")
privat String id2;
// equals and hashCode 구현
...
}
@IdClass와는 다르게 @EmbeddedId를 적용한 식별자 클래스는 식별자 클래스에 기본 키를 직접 매핑한다.
@EmbededId절 적용한 식별자 클래스가 만족해야하는 조건
- @Embeddable 어노테이션을 붙여주어야 한다.
- Serializable 인터페이스를 구현해야한다
- equals, hashCode를 구현해야한다.
- 기본 생성자가 있어야한다.
- 식별자 클래스는 public 이어야 한다.
엔티티 저장하기
Parent parent = new Parent();
ParentId parentId = new ParentId("myId1","myId2");
parent.setId(parentId);
parent.setName("parentName");
em.persist(parent);
엔티티 조회하기
ParentId parentId = new ParentId("myId1", "myId2");
Parent parent = em.find(Parent.class, parentId);
복합 키는 equals()와. hashCode()를 필수로 구현해야 한다.
영속성 컨텍스트는 엔티티의 식별자를 키로 사용해서 엔티티를 관리한다. 그리고 식별자를 비교할 때 equals()와 hashCode()를 사용한다. 따라서 식별자 객체의 동등성이 지켜지지 않으면 예상과 다른 엔티티가 조회되거나 엔티티를 찾을 수 없는 등 영속성 컨텍스트가 엔티티를 관리하는 데 심각한 문제가 발생한다.
'개발 도서 읽기 > 자바 ORM 표준 JPA 프로그래밍' 카테고리의 다른 글
[7장] 7.3.6 식별, 비식별 관계의 장단점 (1) | 2024.11.19 |
---|---|
[7장]7.3.3~7.3.5 복합 키: 식별 관계 매핑 / 일대일 식별관계 (0) | 2024.11.19 |
[7장] 7.2 @MappedSuperclass (0) | 2024.11.19 |
[7장] 7.1 상속 관계 매핑 (1) | 2024.11.17 |
[6장] 6.4.3 다대다 : 연결엔티티 사용 / 새로운 키본 키 사용 (0) | 2024.11.16 |