작성
·
385
답변 2
19
이 강의의 기본 흐름은, Table에서 지원하는 작업들을 어떻게 ORM에서 객체지향적으로 깔끔하게 구현해주느냐의 문제입니다.
Member와 Team 테이블이 있을 때, Member에 외래키가 있겠죠? Member 쪽이 N 이니까.
이 때 DB에서 select 를 사용할 경우 Team을 기준으로 Member와 join하든지, Member를 기준으로 Team과 조인하든지 조회할 때는 어느쪽이나 자유롭게 조회가 가능합니다.
하지만 객체지향은 그렇지가 못하죠.
Member 에서 team을 가져오고 싶다면 member.getTeam()를, team에서 member를 가져오고 싶다면 team.getMembers() 가 가능하도록 각각 테이블에 멤버변수를 추가해주고 이를 ORM이 인식하도록 어노테이션을 붙여주어야 할 것입니다.
여기서 또 다른 문제가 생깁니다.
조회만 할 때는 문제가 없어보였지만 삽입을 할 경우 다음과 같은 코드를 만나면 ORM이 어떻게 처리해야 할까요?
team.addMember(member);
member.setTeam(team);
team에 멤버를 추가하니까 새로운 member를 DB에 insert 하거나 외래키를 update 해주고,
member에 team을 등록시켜주니까 새로운 team 또한 DB에 insert 하거나 외래키를 update 해주고..
뭔가 이상하죠?
외래키 하나로 DB는 자유롭게 양방향 탐색이 가능한것을 객체지향적으로 맞추려다보니 추가적으로 일이 생긴겁니다.
DB에서는 member 테이블의 team관련 외래키만 업데이트하는 방식 외에는 team쪽에서 뭔가 할 수 있는 방법이 없었는데, 객체지향적으로는 team쪽에서 건드려버릴 수 있는 여지가 생긴거예요.
연관관계의 주인이란 것은, 이런 경우 다른 테이블에 영향을 줄 수 있는 명령은 어느 엔티티 객체로 한정지어버릴 것인가? 하는 문제입니다.
연관관계의 주인이 Member 라면 member.setTeam(team); 만 신경을 쓸 것이고, 연관관계의 주인이 Team이라면 team.addMembers(member);만 신경을 쓰겠다는 것입니다.
전자는 DB와 일치하는 패러다임으로 member의 team외래키만 업데이트 해주면 되는 반면, 후자는 JPA가 어거지로 연결해준 것으로 team에서 수정이 시작되었는데 최종적으로는 member 테이블의 team외래키가 업데이트되기 때문에 가급적이면 전자의 방법을 취하는게 좋다고 강의에서 설명하고 있습니다
네 다른 주제들도 결국 DB를 중심으로 보시면 이해가 좀 더 쉬우실 것입니다.
어떤 코드의 결과로 어떤 DB Query가 생성되게 되는지, 그리고 그러한 쿼리를 생성되는 데이터를 어떻게 객체지향적으로 연결시켜 우리가 마치 DB가 아닌 메모리에서 데이터를 가져오는것 만큼이나 편리하게 객체지향적인 코드를 유지시키면서 DB를 사용할 수 있는지를 중점적으로 파악하면 이해에 도움이 되실 것 같습니다.
연관관계의 경우 조금 더 정확하게 부연하자면, 어차피 DB에 최종적으로 저장될 때에는 외래키가 있는 쪽의 테이블을 업데이트하는 수 밖에 없습니다. 그러한 query문을 생성하는 방법은 JPA가 양방향으로 제공해 주는데 (team.addMembers , member.setTeam) 둘 다 유효한 경우는 인정하지 않을테니 둘 중 누가 주인인지만 정해놓고 너가 편한대로 쓰라고 하는 것입니다. (영속성 컨텍스트에서 유효한 한 쪽만 관리하겠다는 느낌으로 보시면 될 것 같습니다)
외래키가 있는 쪽을 연관관계의 주인으로 잡는게 웬만해서 좋다는 의견은 강사님이 여러 해 동안 JPA를 써보면서 내린 결론이니 그 방향성을 따라서 손해보는 일은 없을 것 같고요
0
먼저 정확한 답변 너무나 감사드립니다!
결국엔 맨처음에 말씀하셨던것 처럼 DB와는 다르게 ORM 에서 어떻게 깔끔하게 처리를 하냐를 중점으로 두고 보면 되겠군요 !!
DB에 경우 외래키가 있는쪽에서만 건들면 되지만 객체에서는 둘다 건들수가 있으니 DB처럼 외래키가 있는 쪽에서만 등록 이나 수정이 가능하게 하자는 취지가 있는거네요 ㅎㅎ
너무 정확하게 설명해 주셔서 이해 했습니다 !!