JPA
이번 미션에서는 JPA(Java Persistence API)
에 대해 집중적으로 학습하기 위한 미션으로,
QnA 게시판의 백엔드 로직을 JPA 기반으로 구현하는 것이 목적이었다.
각 단계별로 엔티티 매핑
, 연관 관계 매핑
, 질문 삭제하기 리팩터링
으로 구성되어 있었고,엔티티 매핑
, 연관 관계 매핑
단계에선 각 단계의 제목대로 요구사항이 주어졌다.
QnA 서비스는 User
, Question
, Answer
, DeleteHistory
총 4개의 도메인으로 이루어져 있었으며,
마지막 질문 삭제하기 리펙터링
의 경우 ‘본인이 작성한 질문과 답글만 삭제할 수 있고, 이 이력을 DeleteHistory에
저장해야 한다.’ 라는 요구사항이었다.
하지만 삭제
라고 해서 DB에서 row가 삭제되는 것이 아니라, 삭제 상태(deleted = true)
로 만드는 것이라,
DB에서는 update가 되는 것이고, delete_history 테이블에는 insert가 되는것이므로 도메인의 비즈니스 로직에서 잘 처리해줘야 한다.
또한, 이전 단계에서 엔티티 매핑과 연관 관계 매핑을 잘 처리해놨어야 3단계에서 비교적 매끄럽게 진행이 가능하다.
3단계를 진행하면서 이전에 학습했던 TDD, Refactoring 방법등을 적극 활용하여
이번 미션을 무난하게 진행 할 수 있었다
회고
이번 미션에서 잘 한 점
엔티티 매핑 및 연관관계 매핑
QnA의 시스템 중에서 가장 중요한 연관관계 매핑을 간단히 그려보면 아래와 같다.
DeleteHistory
라는 엔티티의 책임에 대한 고민이 많았다.
속성중에 content_id 라는 Question / Answer의 id를 가지고 있었으나,
이 엔티티의 역할로 보면 History라는 측면에선 연관 관계를 맺지 않았다.
이렇게 설계한 연관 관계가 3단계에서 꽤나 유연하게 설계할 수 있는 밑거름이 되었다.
엔티티 매핑과 연관관계 매핑 단계가 JPA를 잘 알았던 사람이라면 금방 끝낼 수 있는 미션이지만,
각 엔티티의 역할과 책임을 적절히 고려하여 연관관계 매핑을 해줘야 한다는 점 에서
꽤나 오랫동안 고민하며 설계했던 것이 도움이 많이 되었다.
어려웠던 점
엔티티 설계에 대한 깊은 고민
Question 엔티티
1 |
|
Answer 엔티티
1 |
|
두 엔티티를 보면 공통적으로 content
, writer
, id
, deleted
라는 속성을 가지고 있다.
나는 처음에 중복 코드를 최대한 배제하자 라는 생각으로 공통된 속성을 하나의BaseContentEntity
라는 @MappedSuperclass
로 분리하여, 이를 상속받는 구조로 구현을 했다.
1 |
|
하지만, 리뷰어님의 피드백은 BaseContentEntity
는 과도한 책임을 가지고 있는 슈퍼클래스가 되어 버렸고,
추가 확장에 유연하지 못할 것 같다는 의견을 주시며 내 생각이 어떠한지 물어보셨다.😅
각 속성에 대해 다시 한번 고민 해 본 결과
- id : 변경에 유연하지 못하고, MappedSuperclass 보다는 이를 상속받는 근본 Entity가 가지고 있는 것이 더 바람직하다.
- writer : Question / Answer의 writer는 나중에 다른 비즈니스 로직이 적용될 가능성이 높다.
- deleted : 이미 3단계 미션에서 요구사항이 다름(삭제에 필요한 비즈니스 로직이 다르게 전개됨).
따라서, 만약 공통 속성으로 뺀다면content
만 남게 된다.
그렇다면 추가로 고민해볼 것이, content
가 공통 속성으로 뺄만한 가치가 있는가?
–> 그렇지 않다는게 나의 결론이었다. content는 공통 속성으로 뺄만한 복잡한 비즈니스 로직이 없거니와,
만일 뺀다고 했을때 구현 복잡도가 오히려 증가한다는 결론을 내리고, BaseContentEntity를 아예 삭제하는 식으로 다시 원복했다..😭
이제와서 다시 생각해보면, 단일 책임의 원칙으로 고려해봤을 때BaseContentEntity
는 content
와 관련된 역할과 책임만 가지고 있어야 됐다.
느낀점
이번 미션을 진행하면서 가장 크게 느낀점은 JPA는 DataBase를 위한 기술이 아니라, 객체지향설계를 위한 기술 이라는 것이다.
- 각 속성을 어떻게 매핑하는지
- 연관 관계는 어디서 어떤 방향으로(DB의 관계에선 방향이 없다.) 매핑해야 하는지
- 시스템의 설계 상 어떤 임의의 도메인이 다른 도메인과 자주 사용되는지에 따라 변경이 예상되는 부분을 고려
하는 등등.. 여러 가지 측면에서 봤을 때, JPA도 결국은 객체지향을 위한 기술 이라는 것이었다.
이 부분을 크게 간과하고 이번 미션에 임했던 것이 많은 시행착오를 야기시켰다.
JPA 사용 시 엔티티 매핑
, 연관 관계 매핑
단계 에서는 반드시 객체지향적인 설계를 동반해야 한다!
생각해보자
이번 미션을 완료 한 시점에 ‘좋은 객체지향 설계란 무엇인가?’ 라는 의문이 생겼다.
이 질문에 대한 좋은 답을 내고 있는 책을 찾게 되었다.
바로 ‘객체지향의 사실과 오해 - 조영호 지음(위키북스)’ 이다.
개인적으론 이 책을 읽으며 책의 제목 그대로
내가 객체지향에 대해 잘못 알고 있는 부분이 많았다는 것이다.
위 책에 대한 독후감은 다른 포스트에서 좀 더 자세히 다뤄 볼 예정이다.
또한, 기술적으로 바로 도입해볼 수 있는 것들은..
적어도 어떤 개발이라도 객체지향의 5대 원칙(SOLID)를 체크리스트로 만들어서,
원칙을 잘 지키고 있는지를 체크하고 넘어가도 좋을 것 같다는 생각이 든다.🧐