복합키와 식별 관계 매핑
- 식별관계: 부모테이블의 pk를 자식테이블의 pk겸 fk로 사용되는 경우
- 비식별관계: 부모테이블의 pk를 자식테이블의 fk로 사용되고 개별 pk가 존재하는 경우
@IdClass
식별자 클래스 조건
- 식별자 클래스 속성명과 사용하는 클래스 속성명이 같아야 한다
- Serializable 인터페이스 구현 - 왜 구현을 해야하는지 아직은 잘 모르겠음 추가 공부
- 기본생성자, equals, hashCode 구현
- public으로 클래스 지정
@EmbeddedId
IdClass와 다르게 식별자 클래스 자체를 기본키로 매핑을 한다 --> 보다 더 객체 지향스러운 느낌
식별자 클래스 조건
@Embeddable
어노테이션 사용- Serializable 인터페이스 구현 - 왜 구현을 해야하는지 아직은 잘 모르겠음 추가 공부
- 기본생성자, equals, hashCode 구현
- public으로 클래스 지정
매핑 방법
비식별관계 매핑
fk에 대해서 not null조건이 있으면 inner join 만 사용가능하지만 null값이 허용이 된다면 outer join을 사용해야 한다 --> 검색되는 양이 많아짐
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode
public class ParentId implements Serializable {
private String id1;
private String id2;
}
-----------------------------
@Entity
public class Parent{
@Id
@Column(name="PARENT_ID1")
private String id1;
@Id
@Column(name="PARENT_ID2")
private String id2;
}
- 조회 방법
조회 시 복합키를 가지고 조회를 하기 때문에 식별자 클래스를 통해서 조회를 해야한다
Parent parent = new Parent();
parent.setId1("id1");
parent.setId2("id2");
parent.setName("parentName");
em.persist(parent);
em.flush();
em.clear();
ParentId parentId = new ParentId("id1", "id2");//식별자 클래스 사용하여 조회
Parent findParent = em.find(Parent.class, parentId);
아래는 자식 테이블에 fk를 매핑하는 방법이다
@ManyToOne
@JoinColumns({
@JoinColumn(name="ID1", referencedColumnName = "PARENT_ID1"),
@JoinColumn(name="ID2", referencedColumnName = "PARENT_ID2")
//referencedColumnName 동일하면 생략 가능
//@JoinColumn(name="PARENT_ID1"),
//@JoinColumn(name="PARENT_ID2")
})
private Parent parent;
@Entity
public class Parent {
@EmbeddedId
private ParentId id; // 클래스 자체를 직접 매핑
}
-------------------------------------------
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode
@Embeddable
public class ParentId implements Serializable {
@Column(name = "PARENT_ID1")
private String id1;
@Column(name = "PARENT_ID2")
private String id2;
}
식별관계 매핑
식별관계는 자식 테이블이 부모 테이블의 pk를 자신의 pk겸 fk로 가지고 있기 때문에 pk매핑과 연관관계 매핑 두가지를 동시에 해줘야 한다
- @IdClass
@Entity public class Parent { private String id; private String name; }
@Entity
@IdClass(ChildId.class)
public class Child {
@Id
private String childId;
@Id
@ManyToOne
@JoinColumn
private Parent parent;
}
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode
public class ChildId implements Serializable {
private String parent;
private String childID;
}
- @EmbeddedId
```java
@Entity
public class Parent {
private String id;
private String name;
}
@Entity
public class Child {
@MapsId("parent")
@ManyToOne
@JoinColumn
private Parent parent;
@EmbeddedId
private ChildId id;
private String name;
}
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode
@Embeddable
public class ChildId implements Serializable {
private String parent;
private String childID;
}
위 Child 객체에서 @MapsId
에 값을 지정을 하지 않으면 해당 객체내에 있는 @Id
어노테이션으로 지정된 필드의 값을 참조를 한다 하지만 없으면 org.hibernate.AssertionFailure 에러가 난다
일대일 식별관계
일대일 색별관계는 자식테이블이 하나의 pk를 부모 테이블의 pk로 가지면서 fk인 상황이다 그렇기 때문에 복합키의 생성이 필요하지 않다
@Entity
public class Parent{
@Id @GeneratedValue
@Column(name="PARENT_ID")
private String id;
private String name;
@OneToOne(mappedBy="child")
private Child child;
}
@Entity
public class Child{
@Id
private String id;
@OneToOne
@Joincolumn(name="PARENT_ID")
private Parent parent;
private String name;
}
식별관계의 단점
- 부모 테이블의 pk를 자식 테이블로 계속해서 전파--> 테이블의 구조가 유연하지 못한다
- --> 자식 테이블의 pk가 늘어난다
- 복합 키를 만들어야 하는 경우가 많다
식별관계의 장점
- pk인덱스 활용하기 편함
- 특정 상황에 조인 없이 검색가능
참고
책 - 자바 ORM 표준 JPA 프로그래밍
http://www.kyobobook.co.kr/product/detailViewKor.laf?mallGb=KOR&ejkGb=KOR&barcode=9788960777330
'공부기록 > JPA' 카테고리의 다른 글
JPA-값타입 (0) | 2022.01.27 |
---|---|
JPA-프록시 (0) | 2022.01.26 |
JPA 고급매핑1 (0) | 2022.01.20 |
JPA 연관관계 매핑 (0) | 2021.12.29 |
JPA 엔티티 (0) | 2021.12.26 |