berryberrybin / board-project

0 stars 0 forks source link

[JPA] 상속 관계 전략 - User, Customer, Owner 생성 #23

Open berryberrybin opened 1 year ago

berryberrybin commented 1 year ago

3가지 상속관계 Mapping 전략

image

조인 전략

단일 테이블 전략

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

berryberrybin commented 1 year ago

관련 어노테이션

조인전략 코드

// 부모 클래스 
@Entity
@Getter
@Setter
@Inheritance(strategy = InheritanceType.JOINED) // 상속 관계 전략
@DiscriminatorColumn // 부모 클래스에 구분 컬럼을 지정 (기본값 : DTYPE)
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public abstract class User { // abstract 클래스로 생성
    @Id
    @EqualsAndHashCode.Include
    @GeneratedValue(generator = "UUID")
    @Column(name = "user_id", columnDefinition = "BINARY(16)")
    @GenericGenerator(name = "UUID", strategy = "org.hibernate.id.UUIDGenerator")
    private UUID id;

    @Column
    private String nickname;

    public User(String nickname){
        this.nickname = nickname;
    }
}
// 자식 클래스 
@Getter
@Entity
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@DiscriminatorValue("Customer") // 자식 구분 컬럼 설정 
public class Customer extends User { // 부모클래스 상속
    // 자식 클래스에는 id를 넣지 않음
    @Column
    private String address;

    @Column
    private String phoneNum;

    @Builder
    public Customer(final String nickname, String phoneNum, String address) {
        super(nickname);
        this.phoneNum = phoneNum;
        this.address = address;
    }
}
// 자식 클래스 
@Getter
@Entity
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@DiscriminatorValue("Owner")
public class Owner extends User {

    @Column
    private String ownerName;

    @OneToMany(mappedBy = "owner", cascade = CascadeType.ALL, orphanRemoval = true)
    private List<Shop> shopList = new ArrayList<>();

    @Builder
    public Owner(final String nickname, String ownerName) {
        super(nickname);
        this.ownerName = ownerName;
    }
}
image
berryberrybin commented 1 year ago

Repository 코드

// repository
public interface ItemRepository<T extends Item> extends JpaRepository<T, Long> {}
public interface BookRepository extends JpaRepository<Book, Long> {}
public interface AlbumRepository extends JpaRepository<Album, Long> {}
public interface MovieRepository extends JpaRepository<Movie, Long> {}
// test 코드
@RunWith(SpringRunner.class)
@DataJpaTest
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
public class ItemTest {

    @Autowired
    ItemRepository itemRepository;

    @Autowired
    EntityManager entityManager;

    @Before
    public void setUp() throws Exception {
        Movie movie = Movie.builder()
                .actor("kim")
                .name("ABC")
                .price(10000)
                .build();

       Album album = Album.builder()
              .name("가나다")
              .price(20000)
              .article("park")
              .build();

        itemRepository.save(movie); // 부모로 저장해도 됨
        albumRepository.save(album); // 자기 자신으로 저장해도 됨

        entityManager.clear();
    }

    @Test
    public void Item의_서브클래스_객체들_casting으로_가져오기() {
        Movie movie = (Movie) itemRepository.findAll().get(0); // 부모 레파지토리로 찾을 경우 캐스팅 필요함
        assertThat(movie.getName()).isEqualTo("ABC");
    }
}