JPA 상속관계, Inheritence에서 Joined 전략을 사용하기로 합의했습니다. 그런데 여기서 한 가지 문제에 마주치게 됩니다.
가지고 있는 테이블은
부모 User 테이블
자식 Seller 테이블 입니다.
(엔티티도 위와 같습니다)
여기서 User -> Seller 로의 등급 변경이 일어나야 하는데, 이 방법에 대해서 고민해 볼 필요를 느꼈습니다.
User 엔티티에 AllArgsConstructer를 사용해서 Builder 패턴을 적용했습니다. 그 후 User를 상속받는 Seller 엔티티도 Builder를 사용 할 수 있을 줄 알았지만, 그럴 수 없었습니다.
Builder 패턴은 필드에 대한 생성자가 존재하는 상태에서 사용 할 수 있습니다. 따라서 우리는 엔티티 클래스 그 자체에 @AllArgsConstructer 라는 Lombok 어노테이션을 사용해서 Builder를 사용 할 수도 있지만, 이렇게되면 Seller 엔티티는 @Builder 를 사용 할 수 없고(컴파일 오류) 따라서 Builder는 User형태의 Builder로만 사용됩니다.
그렇다면 캐스팅을 하면 되지 않나? (Seller) ~
안됩니다. SQL 테이블의 데이터 무결성을 위해서 위와 같은 캐스팅이 불가능하게 되어 있습니다.
-> 그렇다면 어떻게 해야 할까?
위는 Seller 테이블 그 자체에 Builder 패턴을 사용한 모습입니다. 물론 생성자로 사용해도 문제 없이 돌아가지만, Builder 패턴을 사용해보기 위해, 더하여 한 눈에 잘 보이게 하기 위해서 사용했습니다.
그렇다면 문제가 되었던 승급 부분의 서비스도 살펴봅니다.
위의 if~ 부분은 스프링 시큐리티로 처리 가능하기에 없어도 되는 부분입니다.(팀원분께 곧 말씀드릴 예정)
Seller 객체를 Builder를 이용해서 새로 만들었고, 이것을 save 할 수 있습니다.
근데 정말 되나요?
아뇨 안됩니다.
[Request processing failed;
nested exception is org.springframework.dao.DataIntegrityViolationException:
could not execute statement;
SQL [n/a];
constraint ["PUBLIC.UK_R43AF9AP4EDM43MMTQ01ODDJ6_INDEX_4 ON PUBLIC.USERS(USERNAME NULLS FIRST) VALUES ( /* 2 */ 'admin12' )"; SQL statement:
위와 같이 admin 사용자의 userName 부분이...null이라고 나옵니다. 이것에 대한 해결은 바로 다음 포스팅에서 다루겠습니다.