• 카테고리

    질문 & 답변
  • 세부 분야

    백엔드

  • 해결 여부

    미해결

Kotlin/JPA Inheritance 질문

22.09.08 21:53 작성 조회수 706

1

안녕하세요, Kotlin jpa 코드를 쓰다보니 레퍼런스 코드를 찾기가 쉽지 않은데요.

https://ict-nroo.tistory.com/128

이 블로그 글에 있는 상속 예제 코드를 코틀린으로 옮기면 어떻게 해야할까요?

open class 문제나 primary constructor 로 상위 클래스를 구현하다보니 상속 부분 구현하는데서 생각보다 어려움을 겪고 있습니다.

답변 2

·

답변을 작성해보세요.

1

안녕하세요! Tony님~!!! 즐거운 한가위 보내셨나요?!! 😊 추석이라 답변이 늦었습니다...! 죄송합니다! 😢

빠르게 답변드리자면, 아래와 같이 바꾸어 볼 수 있습니다!


@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
class Item(
  val name: String,

  val price: Long,

  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  val id: Long? = null,
)

@Entity
class Album(
  name: String,
  price: Long,
  val artist: String,
) : Item(name, price)

@Entity
class Movie(
  name: String,
  price: Long,
  val director: String,
  val author: String,
) : Item(name, price)

@Entity
class Book(
  name: String,
  price: Long,
  val author: String,
  val isbn: String,
) : Item(name, price)

이제 여기서 다른 상속 전략을 사용하시면 (그에 따라 어노테이션도 조금 바꿔주실 수 있고요!) 되어요~!!

name과 price에 대해서는 생성자의 파라미터로만 받아 상위 클래스를 초기화하는데 바로 사용했는데요! 아래와 같이 override val을 붙여도 무관합니다.


@Entity
class Book(
  override val name: String,
  override val price: Long,
  val author: String,
  val isbn: String,
) : Item(name, price)

override val을 사용하게 되면 Java클래스로 생각했을 때 Book에도 name와 getName()이 있고, Item에도 name과 getName()이 존재하게 되는데요, 실제 사용에는 큰 문제가 없었습니다!

 

상속 예제를 따라하시는데 어려움이 있으시다면, 우선 JPA를 생각하지 않은 상태에서 상위 클래스와 하위 클래스를 만들어 보신 다음 어노테이션을 추가로 붙여보시면 조금 더 쉬우실 거에요~!! 😊

감사합니다!!! 🙏 남은 연휴도 행복한 시간 되세요~!!

0

Tony님의 프로필

Tony

질문자

2022.09.14

친절한 답변 감사합니다.

혹시 primary constructor 에 구현하는 것과 class 내부에 구현하는 것의 차이가 어떤 차이가 있을까요?

그리고 primary constructor 구현때에 var 와 val 구분도 어떻게 해서 구현하시는지 궁금합니다!

그리고 추가로 이렇게 상속을 할때 API에서는 모든 ITEM을 받고 싶다고 하면 타입을 어떻게 정의해주는게 좋을지 궁금합니다.

Item 으로 했더니 세부 타입들이 무시되더라구요!

안녕하세요~!

  • 혹시 primary constructor 에 구현하는 것과 class 내부에 구현하는 것의 차이가 어떤 차이가 있을까요?

이 질문은 아마 변수를 주 생성자에 넣는 것과 class 내부에 넣는 것의 차이를 여쭤보신 것 같아요! 문법적으로는 생성자를 호출 할 때 해당 파라미터를 의무적으로 받아야 하는지, 그렇지 않은지의 차이가 있고 의미론 적으로는 14강에서 말씀드렸던것처럼 큰 차이가 없습니다! 😊

 

val과 var의 차이는 불변와 가변 여부인데요! 이전 강의인 자바 개발자를 위한 코틀린 입문(Java to Kotlin Starter Guide) 의 1강을 참고해보시면 좋을 것 같아요!!!!

 

  • 그리고 추가로 이렇게 상속을 할때 API에서는 모든 ITEM을 받고 싶다고 하면 타입을 어떻게 정의해주는게 좋을지 궁금합니다.

  • Item 으로 했더니 세부 타입들이 무시되더라구요!

에 대해서는 제가 질문을 이해하지 못했습니다! 🥲

추상화된 인터페이스를 원하시는거라면, https://calatheas.tistory.com/entry/Jackson-%EC%9E%91%EC%84%B1%EC%A4%91-%EC%9D%B8%ED%84%B0%ED%8E%98%EC%9D%B4%EC%8A%A4-%EC%B6%94%EC%83%81%ED%81%B4%EB%9E%98%EC%8A%A4%EC%99%80-%ED%95%98%EC%9C%84%ED%81%B4%EB%9E%98%EC%8A%A4-%EB%93%A4%EC%9D%98-deserializing 와 같이 @JsonTypeInfo 어노테이션을 찾아보시면 도움 되실 것 같습니다!

Tony님의 프로필

Tony

질문자

2022.09.16

Item 이 Movie, Album 등의 세부 상속 타입을 가지고 있을때, 리턴 타입을 어떻게 해야하는지였습니다..!

var/val 질문도 기본적으로 세부 프로퍼티 중 일부는 계속 변하는 값을 가질 수 있을건데, 현재 보여주신 예시 코드에는 모두 val 로만 정의되어 있어서요..!

var 로 또 정의하게되면 setter 를 막아주는 조치를 취하는데 (protected set) 이게 primary constructor 에서는 불가능하지 않은가 싶어서 질문 드렸습니다.

아하~!! 제가 코드를 보지 않고 정확한 말씀을 드리기는 어렵지만.. 😢 추상화된 리턴 타입 말씀이시라면, 가장 상위 타입 (abstract class 또는 interface) 을 반환 타입으로 지정하시고 실제로는 구체화된 하위 타입을 return 하시게 되면 Jackson에서 알아서 역직렬화를 해줍니다~ 😊

 

아 그렇군요!! 제가 작성한 예제에서는 변경되는 지점이 없어 모두 val로 표기하였어요!! 일종의 습관입니다!! ㅎㅎㅎㅎ

네네 맞습니다, primary constructor 내에서 var로 선언도 하고 setter도 막아주는 것은 불가능합니다 ㅠㅠ