데이터 베이스를 설계할 때 다음과 같은 경우를 맞이 한다.
그렇다 이런 관계를 가진 경우 객체에서는 상속 관계를 맺으면 되지만 테이블과 JPA는 어떻게 설계해야할까?
이런식으로 설계할 수 있고, 이를 JPA에서는 @Inheritance
라는 어노테이션을 통해 지원한다.
나는 아래와 같은 상황에서 Inheritance를 적용해서 설계를 개선하였다.
보면, 한개의 인가 테이블에 여러개의 인증 토큰들이 매달려있는 방식이다.
각각은 일대일 매핑으로 null을 허용하고 있었기 때문에, 다음과 같은 문제가 있다고 생각했다.
그래서 다음과 같이 테이블 설계를 변경하였다.
그리고 Jpa 엔티티도 그에 맞게 교체하였다.
@Entity @Table(name = "token")
@Inheritance(strategy = InheritanceType.JOINED)
@DiscriminatorColumn(name = "dtype", discriminatorType = DiscriminatorType.STRING)
@Data @EqualsAndHashCode(of = "id")
@NoArgsConstructor
public abstract class CommonTokenEntity {
@DiscriminatorValue("access_token")
@Entity @Table(name = "access_token")
@Data
@EqualsAndHashCode(callSuper = true)
@NoArgsConstructor
public class AccessTokenEntity extends CommonTokenEntity {
그렇다 이런 궁금증이 들었다. 그렇다면, 추상클래스이자 부모 클래스인 CommonTokenEntity
로 Repository를 생성할 수 있는가?
결과부터 말하면, 있다. 심지어 마음에 들게 동작한다.
내가 작성한 테스트 코드를 한번 보자
@ActiveProfiles("test")
@ExtendWith(SpringExtension.class)
@DataJpaTest
class CommonTokenRepositoryTest {
@PersistenceContext
EntityManager em;
@Autowired
CommonTokenRepository commonTokenRepository;
@Test
@DisplayName("Inheritance Entity 도 repository 로 조회가 가능한지 테스트")
void inheritanceEntityRepositoryAvailable(){
//given
OAuth2AuthorizationEntity authorization = TestEntityFactory.getOAuth2AuthorizationEntity(em);
em.persist(authorization);
AccessTokenEntity accessTokenEntity = TestEntityFactory.getAccessTokenEntity(authorization);
em.persist(accessTokenEntity);
//when
CommonTokenEntity commonTokenEntity = commonTokenRepository.findById(accessTokenEntity.getId())
.orElseGet(() -> fail("조회 실패"));
//then
assertTrue(commonTokenEntity instanceof AccessTokenEntity);
String type = commonTokenEntity.getType();
System.out.println(type);
AccessTokenEntity castedEntity = (AccessTokenEntity) commonTokenEntity;
assertNotNull(castedEntity.getTokenType());
assertEquals(commonTokenEntity.getAuthorization(), authorization);
}
}
이 모든 것이 저 Inheritance 추상클래스의 Repository에서 조회가 된 것이다.
따라서 Inheritance를 통해 엔티티를 설계하면, 한개의 Repository를 통해 좀더 관계 있게 엔티티를 조회할 수 있다.
전체코드는 -> 링크
잘 읽었습니다. 좋은 정보 감사드립니다.