복합키 - 비식별 관계2

PPakSSam·2022년 1월 11일
0
post-thumbnail

복합키 목차

복합키 - 비식별 관계 목차


@EmbeddedId

@EmbeddedId를 사용하면 좀 더 객체지향적인 코드를 작성할 수 있다.

[Parent]

@Entity
public class Parent {
    
    @EmbeddedId
    private ParentId parentId;
    
    private String name;
}

@Embeddable
public class ParentId implements Serializable {
	
    @Column(name = "PARENT_ID1")
    private String parentId1;
    
    @Column(name = "PARENT_ID2")
    private String parentId2;
}

@IdClass로 식별자 클래스 사용시에는 복합키의 속성들을 모두 열거했었다.
하지만 @EmbeddedId를 이용하면 엔티티에 식별자 클래스형만 명시하면 된다.

식별자 클래스에는 @Embeddable 어노테이션을 붙여준다.
그리고 식별자 클래스 조건은 @IdClass와 동일하다.

public static void save(EntityManger em) {
	
    ParentId parentId = new ParentId("PARENT#1", "PARENT#2");
    
    Parent parent = new Parent();
    parent.setParentId(parentId);
    parent.setName("NAME#1");
    em.persist(parent);
}

조회하는 코드는 @IdClass와 같다. 저장시 코드가 달라지는데 좀 더 객체지향적인 코드를 작성할 수 있다는 점이 드러난다. @IdClass는 Parent 객체의 parentId1, parentId2를 set하면 영속화시킬 때 내부적으로 ParentId를 이용한다고 했었다. 그런데 @EmbeddedId를 이용하면 저장시 ParentId를 명시적으로 이용한다.


식별자 클래스가 만족해야하는 조건들


Serializable

Serializable은 직역하면 직렬화를 한다는 의미이다. 직렬화란 객체 또는 데이터를 자바 시스템 외에서도 사용할 수 있도록 Byte 형태로 변환하는 기술이다. (JSON이 대표적인 예시)
Java에서 객체를 참조할 때 주소값을 참조한다. 만약 이를 DB에 저장한다고 가정해보자. 어플리케이션을 재시작하면 이 주소값은 아무런 의미가 없다. 식별자 클래스의 정보를 직렬화하여 DB의 올바른 컬럼에 올바른 값들을 저장하고 나중에 조회할 때도 역직렬화하여 식별자 클래스 객체를 생성해야 하므로 Serializable은 필요하다.

eqauls, hashCode

ParentId id1 = new ParentId();
id1.setId1("myId1");
id1.setId2("myId2");

ParentId id2 = new ParentId();
id2.setId1("myId1");
id2.setId2("myId2");

id1.equals(id2) -> ?

위의 경우 JPA에서id1id2가 같다고 판단해야 해당 식별자 객체로 검색한 엔티티가 같은 엔티티임을 보장할 수 있다. 그래서 eqaulshashCode를 재정의 해야한다.

profile
성장에 대한 경험을 공유하고픈 자발적 경험주의자

0개의 댓글