본문 바로가기
Java/JPA

[JPA_Basic] 상속관계 매핑

by HJ0216 2023. 8. 23.

이 글은 김영한의 [자바 ORM 표준 JPA 프로그래밍 - 기본편] 수강하며 정리한 글입니다.

 

👉 기본 환경

- Language: Java

- DB: H2 Database

- IDE: IntelliJ

 

 

ERD

 

1. JOINED

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import javax.persistence.*;
 
@Entity
@Inheritance(strategy = InheritanceType.JOINED)
@DiscriminatorColumn
public abstract class Item {
 
    @Id @GeneratedValue
    private Long id;
 
    private String name;
    private int price;
 
}
 
 
 

 

🖨️ 실행 결과

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
Hibernate: 
    
    create table Album (
       artist varchar(255),
        id bigint not null,
        primary key (id)
    )
 
Hibernate: 
    
    create table Book (
       ISBN varchar(255),
        author varchar(255),
        id bigint not null,
        primary key (id)
    )
 
Hibernate: 
    
    create table Item (
       DTYPE varchar(31not null,
        id bigint not null,
        name varchar(255),
        price integer not null,
        primary key (id)
    )
 
Hibernate: 
    
    create table Movie (
       actor varchar(255),
        director varchar(255),
        id bigint not null,
        primary key (id)
    )
 
 
Hibernate: 
    
    alter table Album 
       add constraint FKcve1ph6vw9ihye8rbk26h5jm9 
       foreign key (id) 
       references Item
 
Hibernate: 
    
    alter table Book 
       add constraint FKbwwc3a7ch631uyv1b5o9tvysi 
       foreign key (id) 
       references Item
 
Hibernate: 
    
    alter table Movie 
       add constraint FK5sq6d5agrc34ithpdfs0umo9g 
       foreign key (id) 
       references Item
 
 
 

 

📑 특징

- 장점

    - 외래 키 참조 무결성 제약조건 활용가능

    - 저장공간 효율화

- 단점

    - 조회 시, 조인 사용으로 인한 성능 저하

    - 데이터 저장 시, INSERT Query 2번 실행

 

🖨️ INSERT + ITEM 중심 SELECT 실행 결과

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
Hibernate: 
    /* insert jpa_basic.Movie
        */ insert 
        into
            Item
            (name, price, DTYPE, id) 
        values
            (?, ?, 'Movie', ?)
 
Hibernate: 
    /* insert jpa_basic.Movie
        */ insert 
        into
            Movie
            (actor, director, id) 
        values
            (?, ?, ?)
Hibernate: 
    select
        item0_.id as id2_2_0_,
        item0_.name as name3_2_0_,
        item0_.price as price4_2_0_,
        item0_1_.artist as artist1_0_0_,
        item0_2_.ISBN as isbn1_1_0_,
        item0_2_.author as author2_1_0_,
        item0_3_.actor as actor1_4_0_,
        item0_3_.director as director2_4_0_,
        item0_.DTYPE as dtype1_2_0_ 
    from
        Item item0_ 
    left outer join
        Album item0_1_ 
            on item0_.id=item0_1_.id 
    left outer join
        Book item0_2_ 
            on item0_.id=item0_2_.id 
    left outer join
        Movie item0_3_ 
            on item0_.id=item0_3_.id 
    where
        item0_.id=?
 
 
 

 

 

2. SINGLE_TABLE (DEFAULT)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import javax.persistence.*;
 
@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn
public abstract class Item {
 
    @Id @GeneratedValue
    private Long id;
 
    private String name;
    private int price;
 
}
 
 
 

 

🖨️ 실행 결과

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Hibernate: 
    
    create table Item (
       DTYPE varchar(31not null,
        id bigint not null,
        name varchar(255),
        price integer not null,
        artist varchar(255),
        ISBN varchar(255),
        author varchar(255),
        actor varchar(255),
        director varchar(255),
        primary key (id)
    )
 
 
 

 

📑 특징

- 장점

    - 조회 시, 조인이 필요없으므로 성능이 빠름

    - Query가 단순함

- 단점

    - 자식 엔티티가 매핑한 컬럼은 모두 null을 허용해야 함

    - 단일 테이블에 모든 것을 저장하므로 테이블이 과하게 커질 수 있음

    ▶ 그로 인해 성능 저하가 발생할 수 있음

 

🖨️ INSERT + ITEM 중심 SELECT 실행 결과

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
Hibernate: 
    /* insert jpa_basic.Movie
        */ insert 
        into
            Item
            (name, price, actor, director, DTYPE, id) 
        values
            (?, ?, ?, ?, 'Movie', ?)
 
Hibernate: 
    select
        item0_.id as id2_0_0_,
        item0_.name as name3_0_0_,
        item0_.price as price4_0_0_,
        item0_.artist as artist5_0_0_,
        item0_.ISBN as isbn6_0_0_,
        item0_.author as author7_0_0_,
        item0_.actor as actor8_0_0_,
        item0_.director as director9_0_0_,
        item0_.DTYPE as dtype1_0_0_ 
    from
        Item item0_ 
    where
        item0_.id=?
 
 
 

 

 

3. TABLE_PER_CLASS

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import javax.persistence.*;
 
@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
@DiscriminatorColumn
public abstract class Item {
 
    @Id @GeneratedValue
    private Long id;
 
    private String name;
    private int price;
 
}
 
 
 

 

🖨️ 실행 결과

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
Hibernate: 
    
    create table Album (
       id bigint not null,
        name varchar(255),
        price integer not null,
        artist varchar(255),
        primary key (id)
    )
 
Hibernate: 
    
    create table Book (
       id bigint not null,
        name varchar(255),
        price integer not null,
        ISBN varchar(255),
        author varchar(255),
        primary key (id)
    )
 
Hibernate: 
    
    create table Movie (
       id bigint not null,
        name varchar(255),
        price integer not null,
        actor varchar(255),
        director varchar(255),
        primary key (id)
    )
 
 
 

 

🖨️ INSERT + ITEM 중심 SELECT 실행 결과

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
Hibernate: 
    /* insert jpa_basic.Movie
        */ insert 
        into
            Movie
            (name, price, actor, director, id) 
        values
            (?, ?, ?, ?, ?)
 
Hibernate: 
    select
        item0_.id as id1_2_0_,
        item0_.name as name2_2_0_,
        item0_.price as price3_2_0_,
        item0_.artist as artist1_0_0_,
        item0_.ISBN as isbn1_1_0_,
        item0_.author as author2_1_0_,
        item0_.actor as actor1_4_0_,
        item0_.director as director2_4_0_,
        item0_.clazz_ as clazz_0_ 
    from
        ( select
            id,
            name,
            price,
            artist,
            null as ISBN,
            null as author,
            null as actor,
            null as director,
            1 as clazz_ 
        from
            Album 
        union
        all select
            id,
            name,
            price,
            null as artist,
            ISBN,
            author,
            null as actor,
            null as director,
            2 as clazz_ 
        from
            Book 
        union
        all select
            id,
            name,
            price,
            null as artist,
            null as ISBN,
            null as author,
            actor,
            director,
            3 as clazz_ 
        from
            Movie 
    ) item0_ 
where
    item0_.id=?
 
 
 

 

📑 특징

- 장점

    - Not Null 제약 조건 활용 가능

- 단점

    - 여러 자식 테이블을 함께 조회할 때 성능이 느림(UNION SQL 필요)

    - 자식 테이블을 통합해서 쿼리하기 어려움