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
'Backend > Kotlin' 카테고리의 다른 글
Coroutine timeout 설정 (0) | 2022.02.04 |
---|---|
[Kotlin] 코틀린에서 @QueryProjection 사용하기 (0) | 2022.02.03 |
[Kotlin] 함수형 인터페이스 (0) | 2021.12.31 |
[Kotlin] 확장함수 언제 어떻게 사용해야 할까? (0) | 2021.12.24 |
코틀린 with, apply, also, let, run (0) | 2021.12.23 |