상속관계 맵핑1

Mina Park·2022년 9월 10일
0

1.조인 전략

  • 각각 테이블 생성
  • 어노테이션 추가: @Inheritance(strategy = InheritanceType.JOINED)
@Entity
@Inheritance(strategy = InheritanceType.JOINED)
public abstract class Item {

    @Id
    @GeneratedValue
    private Long id;

    private String name;
    private int price;

}
Hibernate: 
    
    create table Album (
       artist varchar(255),
        id bigint not null,
        primary key (id)
    )
Hibernate: 
    
    create table Book (
       author varchar(255),
        isbn varchar(255),
        id bigint not null,
        primary key (id)
    )
Hibernate: 
    
    create table Item (
       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)
    )
  • 등록
public class jpaMain {
    public static void main(String[] args) {
        EntityManagerFactory emf = Persistence.createEntityManagerFactory("hello");
        EntityManager em = emf.createEntityManager();
        EntityTransaction tx = em.getTransaction();
        tx.begin();

        try {

            //movie 등록
            Movie movie = new Movie();
            movie.setDirector("a");
            movie.setActor("b");
            movie.setName("트루먼쇼");
            movie.setPrice(10000);

            em.persist(movie);

            tx.commit();
        } catch (Exception e) {
            tx.rollback();
        } finally {
            em.close();
        }

        emf.close();
    }
}
Hibernate: 
    /* insert hellojpa.mappingAdvanced.Movie
        */ insert 
        into
            Item
            (name, price, id) 
        values
            (?, ?, ?)
Hibernate: 
    /* insert hellojpa.mappingAdvanced.Movie
        */ insert 
        into
            Movie
            (actor, director, id) 
        values
            (?, ?, ?)
  • 조회
    • 조인해서 값을 가져옴
public class jpaMain {
    public static void main(String[] args) {
        EntityManagerFactory emf = Persistence.createEntityManagerFactory("hello");
        EntityManager em = emf.createEntityManager();
        EntityTransaction tx = em.getTransaction();
        tx.begin();

        try {

            //movie 등록
            Movie movie = new Movie();
            movie.setDirector("a");
            movie.setActor("b");
            movie.setName("트루먼쇼");
            movie.setPrice(10000);

            em.persist(movie);

            //movie 조회
            em.flush();
            em.clear(); //영속성 컨텍스트 비우기(1차캐시도 삭제)

            Movie findMovie = em.find(Movie.class, movie.getId());
            System.out.println("findMovie = " + findMovie);

            tx.commit();
        } catch (Exception e) {
            tx.rollback();
        } finally {
            em.close();
        }

        emf.close();
    }
}
Hibernate: 
    select
        movie0_.id as id1_2_0_,
        movie0_1_.name as name2_2_0_,
        movie0_1_.price as price3_2_0_,
        movie0_.actor as actor1_10_0_,
        movie0_.director as director2_10_0_ 
    from
        Movie movie0_ 
    inner join
        Item movie0_1_ 
            on movie0_.id=movie0_1_.id 
    where
        movie0_.id=?
findMovie = hellojpa.mappingAdvanced.Movie@51ec2df1
  • 구분타입(DTYPE)
    • 부모클래스에 @DiscriminatorColum 어노테이션 추가
    • (기본)부모테이블에 "DTYPE"이라는 컬럼을 생성하여 "자식 엔티티명"을 입력
      • (컬럼명 변경)부모클래스에 @DiscriminatorColumn(name = "XXX")
      • (입력값 변경)엔티티명이 아닌 값을 입력하고 싶을 경우 자식클래스에 @DiscriminatorValue("XXX")

📌조인 전략에서는 구분타입 추가는 optional(그래도 실무에서는 사용을 권장)

@Entity
@Inheritance(strategy = InheritanceType.JOINED)
@DiscriminatorColumn
public abstract class Item {

    @Id
    @GeneratedValue
    private Long id;

    private String name;
    private int price;

}

2.단일 테이블 전략

  • 어노테이션 미추가시 JPA가 사용하게 되는 기본전략
  • 부모 테이블에 모든 컬럼 생성
@Entity
public abstract class Item {

    @Id
    @GeneratedValue
    private Long id;

    private String name;
    private int price;

}
@Entity
public class Album extends Item {

    private String artist;

}
@Entity
public class Movie extends Item {

    private String director;
    private String actor;

}
@Entity
public class Book extends Item {

    private String author;
    private String isbn;

}
Hibernate: 
    
    create table Item (
       DTYPE varchar(31) not null,
        id bigint not null,
        name varchar(255),
        price integer not null,
        actor varchar(255),
        director varchar(255),
        author varchar(255),
        isbn varchar(255),
        artist varchar(255),
        primary key (id)
    )
  • 등록, 조회 모두 심플하게 쿼리가 한 번만 실행됨
Hibernate: 
    /* insert hellojpa.mappingAdvanced.Movie
        */ insert 
        into
            Item
            (name, price, actor, director, DTYPE, id) 
        values
            (?, ?, ?, ?, 'Movie', ?)
Hibernate: 
    select
        movie0_.id as id2_0_0_,
        movie0_.name as name3_0_0_,
        movie0_.price as price4_0_0_,
        movie0_.actor as actor5_0_0_,
        movie0_.director as director6_0_0_ 
    from
        Item movie0_ 
    where
        movie0_.id=? 
        and movie0_.DTYPE='Movie'

📌단일 테이블 전략에서는 구분타입이 자동으로 추가됨(어노테이션 안 붙여도)

3.구현 클래스마다 테이블 전략

  • 필요한 속성들을 클래스마다 중복되게 생성
  • 어노테이션 추가: @Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
@DiscriminatorColumn
public abstract class Item {

    @Id
    @GeneratedValue
    private Long id;

    private String name;
    private int price;

}
Hibernate: 
    
    create table Movie (
       id bigint not null,
        name varchar(255),
        price integer not null,
        actor varchar(255),
        director varchar(255),
        primary key (id)
    )

  • 등록, 조회시 필요한 값들을 movie 테이블 하나에서 다 해결
Hibernate: 
    /* insert hellojpa.mappingAdvanced.Movie
        */ insert 
        into
            Movie
            (name, price, actor, director, id) 
        values
            (?, ?, ?, ?, ?)
Hibernate: 
    select
        movie0_.id as id1_2_0_,
        movie0_.name as name2_2_0_,
        movie0_.price as price3_2_0_,
        movie0_.actor as actor1_10_0_,
        movie0_.director as director2_10_0_ 
    from
        Movie movie0_ 
    where
        movie0_.id=?

📌구현 클래스마다 테이블 전략에서는 구분타입 추가가 무의미(추가해도 적용안됨)

0개의 댓글