일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
Tags
- 성능
- APNS
- 푸시
- 웹사이트성능
- 페이스북 번역
- gcm 푸시 번역
- JPA
- redis
- 카프카
- 웹사이트 성능
- nginx
- Design Pattern
- GCM 번역
- 카프카 트랜잭션
- git
- NoSQL
- Push
- 레디스
- 웹사이트최적화기법
- nginx설치
- 자바스크립트
- 푸시 번역
- kafka
- GCM
- php
- Java
- 디자인패턴
- notification
- nginx설정
Archives
- Today
- Total
간단한 개발관련 내용
JPA @Id 를 멤버변수로 선언 VS 생성자로 선언 본문
반응형
코틀린 언어 기반으로 JPA 엔티티의 id 필드를 생성자에 포함시키는 방식과 별도로 필드로 선언하고 protected set을 사용하는 방식은 몇 가지 차이점이 있습니다. 각각의 장단점과 사용 사례를 비교해보겠습니다.
1. id를 생성자에 포함시키는 방식
@Entity
data class Car(
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
val id: Long? = null,
val brand: String,
val model: String
)
특징
- 불변성: val로 선언되므로 생성 후 값이 변경되지 않아 객체가 불변(immutable)에 가까워집니다.
- 초기화 간결성: id 필드도 생성자에서 초기화되므로 Kotlin의 데이터 클래스 특성을 그대로 활용할 수 있습니다.
- 가독성: 코드가 더 간결하고 읽기 쉽습니다.
- 제약 사항:
- JPA는 기본 생성자와 객체 상태를 수정 가능한 상태로 두는 것을 기본으로 설계되었습니다. val로 설정된 id는 JPA 내부적으로 값을 변경할 수 없으므로(불변성) JPA 구현체가 이를 처리하는 데 어려움을 겪을 수 있습니다.
- Hibernate와 같은 JPA 구현체는 종종 리플렉션을 사용하여 필드 값을 설정하기 때문에, 생성자 기반 초기화를 사용할 경우 일부 기능과 충돌할 가능성이 있습니다.
2. 별도 필드 선언 + protected set 사용
@Entity
class Car(
val brand: String,
val model: String
) {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
var id: Long? = null
protected set
}
특징
- JPA 친화적: JPA 구현체가 리플렉션을 통해 id 값을 설정할 수 있도록 필드의 가시성을 protected로 제한합니다. 이는 JPA 스펙과 잘 맞습니다.
- 변경 가능성: var로 선언되었기 때문에, 초기화 후에도 값이 변경될 가능성이 있지만, protected set을 통해 외부에서의 변경을 방지합니다.
- 유연성: JPA의 라이프사이클과 객체 초기화 요구 사항을 모두 만족시킵니다.
- 객체 불변성 저하: 데이터 클래스처럼 불변 객체로 설계하려는 경우 불변성 유지가 어렵습니다.
차이점 요약
특성 생성자 포함 방식 protected set 방식
불변성 | 불변 객체로 설계 가능 (val) | 부분적으로만 불변 (var) |
JPA 호환성 | JPA와 일부 구현체에서 예상치 못한 동작 발생 가능성 있음 | JPA와 완벽히 호환 |
코드 간결성 | 간결하고 읽기 쉬움 | 다소 장황할 수 있음 |
외부 접근 가능성 | id에 대한 외부 접근 불가능 | 외부에서 읽기 가능하지만, 쓰기는 제한 (protected set) |
객체 생명주기 제어 | 생성자 기반으로 초기화가 명확 | JPA 구현체에 의해 객체 생명주기가 제어됨 |
언제 어떤 방식을 사용할까?
- 생성자 포함 방식
- JPA 사용 시 초기화 후 id 값이 변경되지 않도록 설계하고 싶을 때.
- 엔티티를 다른 시스템(예: DDD와 같은 도메인 중심 설계)에서 주로 활용하려고 할 때.
- 데이터베이스 매핑보다는 도메인 객체로서의 역할이 더 중요한 경우.
- protected set 방식
- JPA 호환성을 최우선으로 고려할 때.
- JPA가 엔티티 생명주기를 관리하는 데 완전한 제어권을 가져야 할 때.
- id 값이 외부에서 변경되지 않으면서도, JPA 구현체가 내부적으로 값을 설정할 수 있어야 할 때.
결론
- JPA 친화적이고 일반적으로 사용할 때는 protected set 방식이 더 안전하고 널리 사용되는 방식입니다.
- 하지만 JPA 구현체의 동작을 잘 이해하고 있으며 불변성 유지와 도메인 객체로서의 역할을 중시한다면, 생성자 포함 방식도 사용할 수 있습니다.
두 방식을 혼용하는 것도 가능합니다. 예를 들어, id를 val로 두면서 리플렉션과 기본 생성자를 활용해 JPA와 호환성을 확보할 수 있는 방법을 선택할 수도 있습니다.
반응형