인프런 커뮤니티 질문&답변

박동규님의 프로필 이미지
박동규

작성한 질문수

자바 ORM 표준 JPA 프로그래밍 - 기본편

상속관계 매핑

TABLE_PER_CLASS 전략을 사용했는데 ITEM 테이블이 생겨요.

작성

·

178

0

// JpaMain.java

package hellojpa;

import jakarta.persistence.*;

import java.util.List;

public class JpaMain {

    public static void main(String[] args) {

        EntityManagerFactory emf = Persistence.createEntityManagerFactory("hello");
        EntityManager em = emf.createEntityManager();

        EntityTransaction tx = em.getTransaction();
        tx.begin();

        //code

        try {
            Movie movie = new Movie();
            movie.setDirector("aaaa");
            movie.setActor("bbbb");
            movie.setName("바람과함께사라지다");
            movie.setPrice(10000);

            System.out.println("=== BEFORE ===");
            em.persist(movie);
            System.out.println("=== AFTER ===");

            System.out.println("movie.getId() = " + movie.getId());
            em.flush();
            em.clear();
            System.out.println("movie.getId() = " + movie.getId());

            Movie findMovie = em.find(Movie.class, movie.getId());


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

        }


        emf.close();
    }
}

// Item.java

package hellojpa;

import jakarta.persistence.*;

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

    @Id
    @GeneratedValue
    private Long id;

    private String name;

    private int price;

    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;
    }
}

// Book.java

package hellojpa;

import jakarta.persistence.DiscriminatorValue;
import jakarta.persistence.Entity;

@Entity
public class Book extends Item {
    private String author;
    private String isbn;

}

// Movie.java

package hellojpa;

import jakarta.persistence.DiscriminatorValue;
import jakarta.persistence.Entity;

@Entity
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;
    }
}

// Album.java

package hellojpa;

import jakarta.persistence.DiscriminatorValue;
import jakarta.persistence.Entity;

@Entity
public class Album extends Item {

    private String artist;
}



TABLE_PER_CLASS 전략을 사용했는데도 ITEM 테이블이 생기고 ITEM 테이블에 값이 들어갔는데 왜 이러는 건가요?

답변 2

1

김영한님의 프로필 이미지
김영한
지식공유자

안녕하세요. 박동규님

기존에 남아있던 테이블일 가능성이 높습니다 🙂

매핑 정보를 변경하면, JPA가 테이블을 인지하지 못하므로 drop하지 못하고 DB에 기존 정보가 남아있습니다.

테이블을 삭제하고 다시 실행해보시면 생성되지 않는 것을 확인할 수 있을거에요.

감사합니다.

0

안녕하세요, 인프런 AI 인턴입니다.

박동규님의 질문에 대해, “TABLE_PER_CLASS 전략을 사용했다면 왜 ITEM 테이블이 생성되었는지”에 대한 확실한 대답을 찾기 위해, 과거 유사한 문제에 대한 해결책을 참조하려 합니다.

JPA의 TABLE_PER_CLASS 전략은 각각의 구체 클래스에 대해 별도의 테이블을 생성합니다. 이 경우 Item 클래스와 Item 클래스를 상속받는 Movie, Book, Album 클래스가 있으므로, 이 상속받는 클래스 각각에 대해 별도의 테이블이 생성될 것입니다.

이론적으로 TABLE_PER_CLASS 전략을 사용할 때에는 Item 클래스를 직접적으로 인스턴스화하지 않는 한, ITEM 테이블이 생성되지 않아야 합니다. 그러나 질문자님의 상황을 보면, Item 테이블이 생성되었고, 심지어 데이터가 들어갔습니다. 이는 일반적으로 예상되는 행동이 아니므로, 구성이나 코드의 다른 부분에서 예상치 못한 동작이 일어날 가능성이 있습니다.

관련 자료:

제가 발견한 유사한 문제를 다룬 글은 다음과 같습니다:
- Join 관련 테이블에 데이터 미반영 관련 질문드립니다 - 이 문제는 InheritanceType.JOINED 전략과 관련이 있으며, TABLE_PER_CLASS 전략과 직접적으로 관련되어 있지 않지만, 상속 전략과 테이블 생성에 대한 이해를 돕는 데 유용할 수 있습니다.

이 리소스가 직접적인 해답을 제공하지는 않지만, 상속 전략과 JPA 동작에 대한 깊은 이해를 돕고, 유사한 설정에서 발생할 수 있는 이슈에 대한 해결 방안을 제시합니다.

추가 조치:

  1. JPA 구성 설정을 다시 확인하십시오. 특히 persistence.xml 또는 스프링 부트의 경우 application.properties의 설정을 검토해 보세요.
  2. Item 클래스에 대한 인스턴스 생성 및 저장 로직이 코드 어디에도 없는지 확인하십시오. TABLE_PER_CLASS 전략이 올바르게 적용되었는지도 확인해야 합니다.
  3. Hibernate 또는 사용하시는 JPA 구현체의 버전에 따라 동작이 달라질 수 있습니다. 사용 중인 JPA 구현체와 버전 정보를 검토해 보세요.

저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다.
현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏
추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.

박동규님의 프로필 이미지
박동규

작성한 질문수

질문하기