Backend/Kotlin

[Kotlin] JPA Entity. data class? class?

findmypiece 2022. 2. 3. 17:18
728x90

Spring 가이드에도 나와있듯이 JPA Entity 는 data class가 아닌 일반 class 를 사용하는 것이 권장된다. 사실 data class 를 Entity로 사용하더라도 몇가지만 주의하면 문제될 것은 없지만 일반 class 사용이 권장되는 이유는 data class 를 Entity 로 사용할 경우 data class 답게 사용하지 못하게 된다는 것에 있다.

 

코틀린이 data class 의 특징은 아래와 같다.

  • equals(), hashCode(), toString(), copy() 메소드를 자동으로 만들어준다.
  • copy() 메소드는 얕은복사만 지원하기 때문에 data class 는 불변 클래스로 사용하는 것이 권장된다.
  • 순수하게 데이터만 관리하는 클래스인 만큼 open 키워드를 통한 상속을 지원하지 않는다.

이를 토대로 data class를 Entity 로 사용할 경우 잃게되는 data class를 data class 답지 않게 만드는 이유는 나열하면 아래와 같다.

  • 알다시피 Entity 클래스에 equals(), hashCode(), toString() 가 필요할 경우 반드시 재정의가 필요하다. data class 에서 만들어 주는 메소드도 그대로 사용하면 equals(), hashCode() 우리가 원하는 비교를 제대로 수행할 수 없고 양방향 연관관계(물론 권장되진 않음)일 경우 toString() 는 순환참조 오류를 발생시키게 된다. 어차피 재정의를 해야 한다면 data class의 메소드 자동생성의 이 점을 누릴 수 없다.
  • data class 불변클래스로 사용하는 것이 권장되는데 이 경우 JPA 의 dirty checking 기능을 사용할 수 없다. 물론 data class 를 가변클래스로 사용할 수도 있겠지만 가변클래스로 사용할 거라면 굳이 불변클래스로 사용하는 것이 권장되는 data class 를 사용할 필요가 없다.
  • JPA 의 lazy loading 은 상속을 이용해서 proxy 객체를 만들게 되는데 상속이 막혀있어 의도와 달리 eager loading 으로 동작하게 된다.
    물론 allopen 이라는 gradle 플러그인을 사용하면 컴파일 과정에서 open 이 강제로 추가되어 상속에 사용될 순 있지만 data class 에 open 를 지원하지 않는 것이 코틀린 언어스펙인데 굳이 이를 무시하게 된다.
728x90