티스토리 뷰

Entity 모델링에 VO(value object)를 활용하기

최근 진행하고 있는 Entry3.0 프로젝트에서 ged_grade(검정고시 졸업자 점수)테이블의 grade 컬럼을 unsigned double로 만들었다.

점수를 음수로 저장하는 몽총이는 없으니까 난 스마트하니까~

~

이 테이블을 엔티티로 매핑하려는데 unsigned에 대한 처리는 자바에서 기본적으로 제공하는 기능(문법?)으론 불가능했다. 자바에는 unsigned가 없기 때문이다. 무언가 다른 방법이 필요했다.

그래서 VO를 활용하기로 했다.

먼저 UnsignedDouble이라는 Double을 래핑한 VO를 만들고 @Embeddable을 붙여 Entity에 임베딩할 수 있도록 했다.

**기본 생성자(Default Constructor)가 필요한 이유는 JPA는 조회시 default constructor로 객체를 생성한 뒤 Reflection을 이용해 값을 매핑하기 때문이다.**

이제 GedGrade Entity 클래스에서 UnsignedDouble을 가져다 써보자. (편의를 위해 @Column을 통한 설정은 따로 하지 않았다.)

GedGrade Entity 클래스가 UnsignedDouble을 가져다 쓰도록 하고 실행하자 오류가 발생했다.
Caused by: javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory; nested exception is org.hibernate.MappingException: Repeated column in mapping for entity: com.entry.entrydsm.ged.grade.GedGrade column: value ....(중략) 

@Embedded는 컬럼 명으로 @Embeddable 클래스 내에서 설정한 이름을 사용하기 때문에 4개의 컬럼을 "value"라는 이름으로 매핑을 시도하게되고, 결국 Repeated column 오류가 발생하게 된다.

이 문제는 @AttributeOverride를 이용해 컬럼명을 덮어 씌움(Override)으로써 해결할 수 있다.

**(여러개를 Override하는 경우 `@AttributeOverride`를 묶은 `@AttributeOverrides`를 사용할 수도 있다)**

적용후 오류없이 잘 동작함을 확인할 수 있다.

하지만 Response로서 GedGrade Entity를 던져주면 JSON Serializing 과정에서 UnsignedDouble이 객체로 판정되어 기대했던 JSON 형태와 다른 JSON으로 Serializing되는 이슈가 발생한다.

{     "userId": "user_id",      "grade": {         "value": 1.0     },     "conversionScore": {         "value": 2.0     },     "attendanceScore": 100,     "volunteerScore": {         "value": 100.0     },     "finalScore": {         "value": 100.0     } }

우리가 원한 건 이게 아닌데...

해결하는 방법은 JPA의 범주를 벗어나기 때문에 다른 게시글로 다뤄야겠다.