본문 바로가기
개인 공부/JPA

실전 예제 4. 상속 관계 매핑

by hanyugyeong 2023. 8. 2.
반응형
SMALL

요구사항 

1) 상품의 종류는 음반, 도서, 영화가 있고 이후 더 확장될 수 있다. 

2) 모든 데이터는 등록일과 수정일이 있어야 한다. 

 

상속 관계 매핑

상품 클래스를 jpabook.model.entity.item이라는 패키지로 이동했다. 이 패키지에는 상품과 상품의 자식 클래스들을 모아두었다. 그리고 상품 클래스는 직접 생성해서 사용하지 않으므로 abstract를 추가해서 추상 클래스로 만들었다. 

부모 엔티티 상품(ITEM)

@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE) // 1번
@DiscriminatorColumn(name="DTYPE") // 2번
public abstract class Item {

	@Id @GeneratedValue
	@Column(name="ITEM_ID")
	private Long id;

	private String name; //이름
	private int price; //가격
	private int stockQuantity; //제고수량

	@ManyToMany(mappedBy = "items")
	private List<Category> categories = new ArrayList<Category>();

	public Long getId() {
		return id;
	}

	public void setId(Long id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getPrice() {
		return price;
	}

	public void setPrice(int price) {
		this.price = price;
	}

	public int getStockQuantity() {
		return stockQuantity;
	}

	public void setStockQuantity(int stockQuantity) {
		this.stockQuantity = stockQuantity;
	}

	public List<Category> getCategories() {
		return categories;
	}

	public void setCategories(List<Category> categories) {
		this.categories = categories;
	}

	@Override
	public String toString() {
		return "Item{" +
			"id=" + id +
			", name='" + name + '\'' +
			", price=" + price +
			", stockQuantity=" + stockQuantity +
			", categories=" + categories +
			'}';
	}
}

1) 상속 관계를 매핑하기 위해 부모 클래스인 Item에 @Inheritance 어노테이션을 사용하고 strategy 속성에 InheritanceType.SINGLE_TABLE을 선택해서 단일 테이블 전략을 선택했다. 

2) 단일 테이블 전략은 구분 칼럼을 필수로 사용해야 한다. @DiscriminatorColumn 어노테이션을 사용하고 name 속성에 DTYPE이라는 구분 칼럼으로 사용할 이름을 주었다. 참고로 생략하면 DTYPE이라는 이름을 기본으로 사용한다.

 

자식 엔티티 매핑

@Entity
@DiscriminatorValue("A")
public class Album extends Item{
	private String artist;
	private String etc;

	public String getArtist() {
		return artist;
	}

	public void setArtist(String artist) {
		this.artist = artist;
	}

	public String getEtc() {
		return etc;
	}

	public void setEtc(String etc) {
		this.etc = etc;
	}
	@Override
	public String toString() {
		return "Album{" +
			"artist='" + artist + '\'' +
			", etc='" + etc + '\'' +
			'}';
	}
}
@Entity
@DiscriminatorValue("B")
public class Book extends Item{
	private String author;
	private String isbn;

	public String getAuthor() {
		return author;
	}

	public void setAuthor(String author) {
		this.author = author;
	}

	public String getIsbn() {
		return isbn;
	}

	public void setIsbn(String isbn) {
		this.isbn = isbn;
	}

	@Override
	public String toString() {
		return "Book{" +
			"author='" + author + '\'' +
			", isbn='" + isbn + '\'' +
			'}';
	}
}
@Entity
@DiscriminatorValue("M")
public class Movie extends Item {

    private String director;
    private String actor;

    public String getDirector() {
        return director;
    }

    public void setDirector(String director) {
        this.director = director;
    }

    public String getActor() {
        return actor;
    }

    public void setActor(String actor) {
        this.actor = actor;
    }

    @Override
    public String toString() {
        return "Movie{" +
                "director='" + director + '\'' +
                ", actor='" + actor + '\'' +
                '}';
    }
}

자식 테이블들은 @DiscriminatorValue 어노테이션을 사용하고 그 값으로 구분 칼럼(DTYPE)에 입력될 값을 정하면 된다. 각각 앞자리를 따서 A,B,M으로 정했다

@MappedSuperclass 매핑 

모든 엔티티에 등록일과 수정일을 직접 추가하는 것보다는 @MappedSuperclass를 사용해서 부모 클래스를 만들어 상속받는 것이 효과적이다. 

기본 부모 엔티티 (BaseEntity)

@MappedSuperclass
public class BaseEntity {
	private Date createdDate; //등록일
	private Date lastModifiedDate; //수정일

	public Date getCreatedDate() {
		return createdDate;
	}

	public void setCreatedDate(Date createdDate) {
		this.createdDate = createdDate;
	}

	public Date getLastModifiedDate() {
		return lastModifiedDate;
	}

	public void setLastModifiedDate(Date lastModifiedDate) {
		this.lastModifiedDate = lastModifiedDate;
	}
}

매핑 정보를 상속

@Entity
public class Member extends BaseEntity{
}
@Entity
@Table(name="ORDERS")
public class Order extends BaseEntity{
}

자동 생성된 DDL

create table Member (
       MEMBER_ID bigint not null,
        createdDate timestamp,
        lastModifiedDate timestamp,
        city varchar(255),
        name varchar(255),
        street varchar(255),
        zipcode varchar(255),
        primary key (MEMBER_ID)
    )
반응형
LIST

'개인 공부 > JPA' 카테고리의 다른 글

05 연관관계 매핑 기초  (0) 2023.10.04
04 엔티티 매핑  (0) 2023.09.20
03 영속성 관리  (0) 2023.09.19
02 JPA 시작  (0) 2023.09.19
08 프록시와 연관관계 관리  (0) 2023.08.03