공부기록/JPA

JPA-고급매핑2

jhs0129 2022. 1. 20. 18:56
320x100
반응형
320x100

복합키와 식별 관계 매핑

  • 식별관계: 부모테이블의 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

320x100
반응형