Open berryberrybin opened 1 year ago
@Inheritance(strategy = InheritanceType.JOINED)
@DiscriminatorColumn
@DiscriminatorValue("A")
@DiscriminatorValue("B")
// 부모 클래스
@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;
}
}
// 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");
}
}
3가지 상속관계 Mapping 전략
슈퍼타입 서브타입 관계
라는 모델링 기법이 존재함객체의 상속 구조
와데이터베이스의 슈퍼타입 서브타입 관계
를 매핑하는 것을 상속관계 매핑이라 함조인 전략
부모테이블의 기본키(PK)
를 자식 테이블이 받아기본키(PK) + 외래키(FK)
로 사용하는 전략DTYPE
이란 구분 컬럼을 사용함단일 테이블 전략
구현 클래스마다 테이블 전략