-
DDD. ORM과 투명한 영속성 4부JAVA/DDD 2021. 1. 24. 06:22
ENTITY의 식별자(Identity)
- ENTITY는 추적해야할 도메인 개념이 시간과 장소에 따라 다양한 형태를 지닐 수 있다는 개념을 도메인 모델에 도입한다.
- 따라서 변화되는 ENTITY의 모든 형태가 공유할 수 있는 일반적인 식별자의 개념을 필요로 한다.
- REFERENCE OBJECT의 경우처럼 식별자를 단순히 객체 생성 시에 할당되는 메모리 주소로만 한정해서 생각한다면 데이터베이스 레코드의 형태를 띈 도메인 개념을 ENTITY로 간주할 수는 없을 것이다.
- 따라서 생명주기에 걸쳐 구현 기술과 무관하게 각 ENTITY의 유일성을 보장할 수 있는 속성을 식별자로 삼아야 한다.
- 그렇다면 ENTITY의 식별자로 적당한 속성의 특징은 무엇일까?
- 무엇이 구현 기술과 무관하게 ENTITY의 유일성을 보장할 수 있을까? 이에 대한 해답을 데이터베이스 테이블의 후보 키(candidate key) 식별 방법으로부터 얻을 수 있다.
- 일반적으로 테이블의 후보 키는 다음과 같은 특징을 가진다.
특징
- 후보 키의 모든 컬럼 값은 NULL이 아니어야 한다.
- 각 로우는 유일한 값을 가진다.
- 값이 결코 변경되어서는 안된다.
- 데이터베이스 모델링에서는 이런 특성을 가진 후보 키중 가장 적절한 것을 주 키(primaey key)로 삼는다.
- 나머지 후보 키들은 테이블의 유일 키(unique key)로 선택된다.
- 동일한 특성이 ENTITY의 식별자에도 적용될 수 있을까? 그렇다고 생각한다.
- 데이터베이스 테이블에 저장된 레코드는 ENTITY의 특별한 형태라고 볼 수 있다.
- ENTITY가 여러 형태를 거쳐 소멸될 때까지 유일성과 추적성을 보장하는 방법은 영속성 메커니즘에 동일하게 적용될 수 있는 식별자를 사용하는 것이다.
- 이런 관점에서 데이터베이스의 모델링 과정을 ENTITY 중심의 프로세스로 설명할 수 있다.
- 시스템에서 지속적으로 관리해야 할 ENTITY를 식별하고, 해당 ENTITY의 유일성과 추적성을 보장하는 속성들을 찾아 ENTITY의 후보 식별자로 선택한다.
- 후보 식별자 중 해당 ENTITY에 가장 적절한 후보 식별자를 선택하여 ENTITY의 최종 식별자로 삼는다.
- 이 기반 모델로부터 데이터베이스의 논리/물리 모델을 도출하고 주 키와 유일 키를 식별한다.
- 이것을 ENTITY라는 개념을 중심으로 데이터 모델링의 3단계인 개념 모델링, 논리 모델링, 물리 모델링을 확장한 것으로 보아도 무방하다.
- 기반 모델을 정제하여 도메인 모델을 발전시켜 가면서 선택된 식별자를 ENTITY의 속성으로 모델링한다.
- ENTITY의 식별자는 테이블의 주 키와 동일할 것이다.
- 바꾸어 말하면 ENTITY는 테이블의 주 키를 속성으로 가질 것이다.
- 만약 ENTITY의 생명주기 중 XML 형태로 표현될 필요가 있다면 ENTITY의 식별자가 XML의 엘리먼트로 표현될 것이다.
- 식별자에 대한 이런 관점은 MODEL-DRIVEN DESIGN 개념을 기반으로 한다.
- 즉, 통일된 하나의 기반 모델을 사용하여 소프트웨어 개발을 주도하는 것이다.
- 이를 통해 소프트웨어 개발 과정을 분리된 개별 활동이 아닌 하나의 큰 흐름으로 볼 수 있도록 하는 정신적 틀을 제공한다.
- 너무 이론적인 관점인 것 같다면 실용적인 관점에서 식별자를 바라보도록 하자.
- 거의 모든 엔터프라이즈 어플리케이션은 영속성 메커니즘으로 관계형 데이터베이스를 사용한다.
- 따라서 ENTITY의 관점에서 영속성과 추적성, 그리고 유일성을 보장받을 수 있는 가장 좋은 방법은 데이터베이스 테이블의 주 키를 식별자로 사용하는 것이다.
- 메모리 내에 생성된 ENTITY가 데이터베이스의 한 로우로 맵핑될 수 없다면 데이터베이스를 영속성 저장소로 사용하는 시스템에서 ENTITY를 추적할 수 없을 것이다.
- 따라서 ENTITY는 객체와 데이터베이스 레코드와의 추적성을 보장하기 위해 주 키를 속성으로 포함해야 하며 데이터베이스와 맵핑하기 위해 이 속성을 사용해야 한다.
- 이처럼 도메인 모델 작성 시 데이터베이스의 주키를 ENTITY의 식별자로 포함시키는 것을 IDENTITY FIELD 패턴이라고 한다.
- 이제 우리는 도메인 객체를 식별하기 위해 사용되는 3가지 식별자의 개념을 모두 살펴보았다.
정리
- 두 오브젝트가 동일한 메모리 주소를 공유한다면 이들은 동일하다. 이것은 “==” 연산자를 사용하여 확인할 수 있다. 이것을 객체 식별자(object identity)라고 한다. 우리는 REFERENCE OBJECT를 살펴보면서 객체 식별자의 개념을 살펴보았다..
- 두 오브젝트가 동일한 값을 가진다면 이들은 동등하다. 이것은 equals(Object o) 메소드를 사용하여 확인할 수 있다. 이것을 동등성(equality)이라고 한다. 우리는 값 객체를 살펴보면서 동등성의 개념을 살펴 보았다.
- 두 오브젝트가 데이터베이스의 동일한 로우에 저장되어 있을 경우, 즉 동일한 테이블과 동일한 주 키를 공유한다면 오브젝트는 동일하다. 이것을 데이터베이스 식별자(database identity)라고 한다.
데이터베이스 식별자를 ENTITY의 식별자로 사용하기 위해서는 객체의 동일성을 확인하기 위해 IDENTITY FIELD를 비교해야 한다.
따라서 단순히 REFERENCE OBJECT처럼 “==”를 사용하여 동일성을 비교할 수 없으며 VALUE OBJECT의 경우처럼 equals()를 오버라이딩해야 한다.
차이점이라면 VALUE OBJECT가 속성으로 가지는 모든 값들을 비교하는 반면, ENTITY는 데이터베이스 키를 비교한다는 점이다.
- 단 데이터베이스 테이블에서 대리 키(surrogate key)를 주 키로 사용하는 경우에는 대리 키 대신 자연 키(natural key)를 비교해야한다.
- 대리 키를 비교할 경우 영속성 객체가 비영속 상태(transient state)나 준영속 상태(detached state)일 때 해쉬 기반 처리가 오작동할 우려가 있기 때문이다.
- 이처럼 테이블의 주 키로 대리키가 사용될 경우 동등성 비교를 위해 자연 키를 사용하는 것을 “비즈니스 키 동등성(business key equality)”이라고 한다.
- 자세한 내용은 Gavin King의 저서 “Java Persistence with Hibernate” Chapter 9을 참조하자.
- equals()를 오버라이딩할 때마다 hashCode() 역시 오버라이딩해야함을 잊지 말자. 두 오브젝트가 동등하다면, 동일한 해쉬 코드를 가져야 한다.
- ENTITY의 생명주기와 식별자의 개념을 살펴보았으니 이제 REPOSITORY를 구현하기 위해 필요한 ORM 기술에 관해 살펴보도록 하자.
참조
'JAVA > DDD' 카테고리의 다른 글
DDD - ORM과 투명한 영속성 6부 7부 (0) 2021.01.24 DDD - ORM과 투명한 영속성 5부 (0) 2021.01.24 DDD. ORM과 투명한 영속성 3부 (0) 2021.01.23 DDD. ORM과 투명한 영속성 2부 (0) 2021.01.23 DDD. ORM과 투명한 영속성 1부 (0) 2021.01.23