Closed jeongmin0709 closed 1 year ago
댓글 저장 기능을 2번 방식으로 구현한다고 했을 때, 결국 DB에 쿼리를 날려서 데이터를 갖고와야하는 것은 동일한가요?
넵 2번방식은 저장하고 member data를 db에서 다시 가져와야겠죠.
그럼 3번 방식을 채택하는게 좋을거같네요. 모든 코드에 3번 방식을 적용해 놓은 다음에, (과도한 repository의 주입을 막기 위한) 저장 후 연관된 엔티티의 데이터가 필요하지 않은 로직에 2번 방식을 적용하는건 고민을 해보면 좋을거 같아요
3번방식은 1번방식이랑 repository 주입은 같습니다. 다만 성능적으로 insert할떄 select를 안날리는 거죠, 그래서 절충안이라고 한거였어요
네네 그러니까 지금 고민중인 포인트 2가지가
이건데, getOne()을 사용해서 1번 문제는 해결하는 것으로 하고, 위의 댓글에 써놓은 것 처럼 '과도한 Repository의 주입을 막기 위해' 임시엔티티를 사용하는 방식은 좀 더 고민해볼필요가 있는 것 같아요. Repository가 과도하게 주입되는 건 막는게 좋지만, 필요한 경우에는 주입해야하니까요.
넵 그래서 필요한경우에는 주입을 해야한다고 생각합니다. 제가 위에서 예시를 들어놓은 것처럼 reply를 저장하고 반환할때 member의 데이터가 필요하다면 memberRepository를 주입받는 거죠. 해당 상황에서는 1번과 3번의 성능은 동일합니다. proxy member 를 만든 후 저장해도 결국 member에 접근해서 데이터를 가져올떄 select문이 나갈테니까요.
넵 그럼 일단 제가 사용했던 1번 방법은 3번 방법으로 수정하도록 하겠습니다.
코드짜다가 보니까 getOne()은 Deprecated 되었네요. 대신 getReferenceById를 사용하면 될 것 같습니다.
https://jgrammer.tistory.com/entry/JPA-%EB%B9%84%ED%9A%A8%EC%9C%A8%EC%A0%81%EC%9D%B8-%EC%97%B0%EA%B4%80-%EA%B4%80%EA%B3%84-%EC%A0%80%EC%9E%A5-%EB%B0%A9%EC%8B%9D-%EA%B0%9C%EC%84%A0%EB%B6%88%ED%95%84%EC%9A%94%ED%95%9C-select%EB%AC%B8-%EC%A0%9C%EA%B1%B0 위에 링크를 보고 연관관계 엔티티를 저장하는 방식이 총 3가지 정도 있다는 것을 알게되었습니다.
현재 제가 사용하고 있는 방법은 2번, 세승님이 사용하고 있는 방법은 1번입니다.
1번의 경우 미리 연관관계 엔티티가 있는지 확인한 후 저장하기 때문에 예외상황을 좀더 세부적으로 나눌 수 있다는 장점이 있지만 insert문 이전에 연관관계가 있는 객체 숫자에 비례하여 select를 하고 저장하기 때문에 성능적으로 떨어지고 관련 repository를 모두 의존성 주입을 하여 결합도가 올라간다는 단점이 있다고 생각하여 사용하지 않고 있었습니다.
2번의 경우 임시엔티티를 만들어 저장하기 때문에 insert문 이전에 select문이 발생하지 않고 관련 repository 를 의존성 주입 하지 않기때문에 객체지향적으로 좋은 방법이라고 생각하여 사용하는 중이지만 저장 후 바로 연관된 엔티티의 데이터 까지는 반환 할 수는 없는 단점이 있습니다. 그래서 가끔 NullpointerException이 터질때도 있습니다. 임시 엔티티에는 아이디 값만 들어가 있기 떄문에 관련된 데이터를 얻으려면 select를 한번 더 날려야합니다.
3번의 경우 1번과 2번의 절충안 이라고 생각합니다. 연관된 엔티티의 repository를 모두 주입받아야 하지만 select 문을 실행하지 않고 insert만 실행하기 떄문에 성능적으로 이점이 있습니다. 2번의 단점인 NullpointerException이 터지지 않기 떄문에 안정성도 2번보다 좋습니다.
위에 3개 모두 장단점이 있고 필요한 상황에 맞게 쓰는게 필요하다고 생각합니다. 1번의 경우 저장 후 바로 연관된 엔티티의 데이터를 반환해야 할때 사용하면 좋다고 생각합니다. 2번의 경우 저장 후 연관된 엔티티의 데이터가 필요하지 않다면 사용하는게 좋다고 생각합니다. 3번의 경우 1번과 2번을 둘다 대체할 수 있어서 1번 2번을 사용하지 않고 3번만 사용하는 방법도 있습니다.
댓글 저장 기능의 경우 저장 후 회원의 닉네임과 이미지 경로를 반환해야 하기 때문에 1번 방식이나 3번 방식을 사용하는게 좋다고 생각하고 있고 2번 방식으로도 구현이 가능하긴 합니다.