어떤 프로젝트를 만들 때 유저의 권한이 여러 개로 분리된다면, Enum 클래스를 활용하여 Role을 체크하는 식으로 만들면 편합니다. 스프링 시큐리티의 preAuthorize(hasRole = " ~ " ) 기능을 사용해서 인가 처리를 하기도 쉽죠.
그래서 우리는 User라는 하나의 테이블에서 RoleEnum을 사용해서 모든것을 처리했습니다.
그런데, 데이터 테이블의 입장에서 보면 조금 애매해집니다. 예를 들어봅시다.
오늘 프로젝트를 시작하면서 우리는 권한을 세 개로 분리해야 된다는 명세를 전달 받았습니다.
일반 유저(Buyer)
판매자 유저(Seller)
관리자 유저(Admin)
바로 이전 프로젝트에 사용했던 것처럼 Enum을 사용해서 그 권한을 분리했습니다.
여기서 문제는 user 테이블에 storeName이라는 불필요한 칼럼이 들어간다는 것입니다.
이 storeName 은 회원가입 할 때는 값을 기입받지 않습니다. 구매자가 판매자로의 권한 상승을 요청하면, 이 storeName 과 함께 별도의 Request를 Body형태로 보내고, 그 Request를 받아서 유저 테이블에있는 "실제 요청을 보낸 유저"를 찾아서 값을 insert 해줘야 합니다.
다음은 팀 노션에도 공유한 제가 정리한 문제들입니다.
User를 자바의 "상속" 으로 처리하는 것이 나은 이유
그렇다면 어떤 테이블이 바람직할까요?
위와 같이 데이터 테이블의 구조를 만들게 되면 더 좋겠네요! 근데 Spring, JPA로 사용하는 방법은?
위 참조자료에도 나왔는데, JPA의 부모 테이블에 @Inheritence(strategy = InheritenceType."
") 와 같이 사용합니다. 직접 볼까요?
위와 같이 어노테이션을 달아줬습니다.
User <부모>
Buyer/Seller/Admin <자식>
위와 같은 형태가 자연스러우므로, JOINED 를 사용했습니다.
실험적으로 사용한 모습입니다. Entity 에 꼭 필요한 @Id 만드세요~ 라는 컴파일 에러가 뜨지 않는 모습입니다. @ID는 부모객체의 User에서 사용하고, 또한 필드값 또한 부모의 것을 따릅니다.
이 클래스 안에 새로운 필드를 정의하면, 서브타입 테이블로 Seller라는 테이블은 유저의 필드값 + Seller 만의 not null한 필드값을 가지게 될 것입니다.
뭔가 허전하신가요?
@DiscriminatorColumn 은 구조상 부모가 되는 것이 자명한 엔티티에게 붙여주는 어노테이션 입니다.
@DiscriminatorColumn(name="dtype")이 디폴트로 되어 있지요.
이 친구의 역할은 다음과 같습니다.
어떤 컬럼을 가지고 어떤 자식 엔터티를 판별할 것인가에 대한 힌트를 주는 어노테이션!
즉, 우리가 실제로 사용 할 예제는 User 와 Sellers...등의 테이블이며
이들은 Role에 의해서 구별됩니다. 우리는 이 어노테이션을 다음과 같이 사용 할 수 있을 것입니다.
위처럼 실제 구분의 기준이 되는 role로써 Discrimination 하도록 만들었습니다. 자식 엔티티에도 이에 상응하는 어노테이션을 붙여봅시다.
위와같이 사용했습니다.
-> Dtype을 이미 필드에 정의된 role로 하면 에러가 발생합니다. 디폴트로 변경했습니다.
제가 필요로 했던 정보입니다. 정말 정리를 열심히 하셨네요b