-
Notifications
You must be signed in to change notification settings - Fork 6
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[BE] Refactor/#540 지연로딩의 경우, soft delete을 반영할 수 없는 문제 해결 #553
Conversation
- 검토할 TODO 다수 존재
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
수고하셨습니다 도이!
질문하나 남기긴했는데 merge 되도 무방하다고 생각하여 approve 남깁니다 👍👍
permissionRepository.deleteAllByMemberId(memberId); | ||
atlasRepository.deleteAllByMemberId(memberId); | ||
bookmarkRepository.deleteAllByMemberId(memberId); | ||
entityManager.flush(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Spring Data JPA의 Repository 인터페이스에는 flush 메서드가 기본적으로 포함되어있어서
해당 메서드를 사용하는 경우, 내부적으로 EntityManager의 flush 메서드가 호출된다고 하네용!
entityManager를 주입받을 필요없이 repository에서 flush하는 건 어떨까요??
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
추가적인 주입이 필요없다는 면에서 굉장히 좋은 아이디어네요!
하지만 현재 코드는 Permission
, Atlas
, Bookmark
에 대한 hard delete
쿼리를 한꺼번에 날리는 flush
이기 때문에, flush
를 호출하는 의무를 어떠한 Repository
가 가져가야 하는지를 정하는 것도 굉장히 애매한 부분인 것 같기도 하네요.
다들 어떻게 생각하시나요?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
사실 저도 entityManager
가 존재한다는게 거슬리긴 해요.
준팍이 말씀해주신
entityManager를 주입받을 필요없이 repository에서 flush하는 건 어떨까요??
이 부분은 별도의 설정하지 않아도 된다는 의미일까요 ?
아마, 테스트 코드 구성을 잘못해서 발생한 문제를 해결하기 위해 위와같은 구조를 갖게 된 걸로 알고있어요. (내가 짬 ㅋ)
테스트 코드에서 //given
에서 데이터를 세팅해주는 작업과 같은 트랜잭션으로 묶이기 때문에 flush
를 강제로 호출해주지 않으면 수정 관련 쿼리가 쓰기 지연 저장소에 저장되었다가, 트랜잭션이 커밋되기 직전에 데이터베이스로 쿼리를 날라가게 되요.
어떻게 해결 할 수 있다는 의미인지 궁금합니다 !
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
맞아요! 다른 경우처럼 Repository 메서드를 호출하는 것만으로 flush를 처리하면 좋겠지만,
지금은 Transactional로 묶여있는 메서드라 서비스 메서드 호출이 끝날때 한번에 flush하지 않나요..?!
그래서 위 경우 Topic, Pin, PinImage의 soft delete 쿼리(update)를 날리기 전에
Permission, Atlas, Bookmark 에 대한 hard delete 쿼리를 먼저 날려주는 처리가 필요했어요.
하지만 저도 EntityManager에 대한 의존성을 없애는 게 좋다고 생각하는데,
그러려면 @Query
를 쓰더라도 @Modifying
으로 flush automatically 해주는 게 좋을까요?
아니면 더 좋은 방법을 아신다면 공유 부탁드립니다 !! 🥲
중간에 flush를 해줘야 하는 이유
72번 줄이 없을 경우, 예외는 발생하지 않았지만 hard delete 메서드 호출이 DB에 반영되지 않는 것을 확인할 수 있었어요.
(테스트, 로컬 POSTMAN 확인 모두)
제가 추측하는 플로우는 아래와 같습니다.
중간에 flush를 해주지 않고 쓰기 지연으로 한 번에 flush할 경우 아래와 같은 순서로 동작하는 것 아닐까요?
- hard delete 메서드를 통해 해당 id를 가진 엔티티를 영속성 컨텍스트에서 제거한다.
- soft delete 메서드를 통해 update를 호출하면서, 연관된 엔티티들이 모두 영속화된다.
-> (1)에서 delete 해도, 2에서 조회할 때 함께 불러와지는 permission, atlas, bookmark까지 다시 영속화된다. - 그래서 한 번에 flush할 때 delete 쿼리가 나가지 않는다.
그래서 (1)과 (2) 사이에 직접 flush를 해야 한다고 생각했어요.
제가 아직 헷갈려서 정리하다보니 길어졌네요.. ㅎㅎ 그래도 참고차 남깁니다.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
아니 제가 화면 새로고침을 안해서 쥬니 댓글 지금봤네용 하핫
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
세 레포지터리 중 어떤 것을 써도 동일하게 동작할텐데
매튜 말대로 뭐 써야될지 조금 고민되긴 하겠네요 ㅋㅋ
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
아 아까 트러블슈팅하다가 clear까지 해보려고 entityManager를 받아왔다가 이 생각을 못했네요 !!
근데 대신 delete 메서드에 JPQL 직접 쓰고 Modifying 으로 해결하는 건 어떠세요?
쥬니가 쓴 기술 블로그 참고
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
좋습니다 ㅎㅎ
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
오우 도이!
where 절을 적용하면서 isDeletedFalse 가 떨어져버리니까 굉장히 메서드가 짧아졌군요!
고생하셨습니다!
낭낭하게 코멘트 남겼습니다~!
확인해주시고 대댓글을 달아주시기를 원하기 때문에 Request Changes 남기도록 하겠습니다 ^.^
확인하시면 바로 Approve 로 바꾸도록 할게요~!
Pin pin = pinRepository.findById(pinId) | ||
.orElseThrow(() -> new PinNotFoundException(PIN_NOT_FOUND, pinId)); | ||
|
||
/// TODO: 2023/10/05 soft delete를 @Query로 구현하면서, pinCount 반영을 통합할 수 없음 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
update pin p, topic t
set p.is_deleted = true, t.pin_count = t.pin_count - 1
where p.id = "삭제하려는 pin id" AND t.id = p.topic_id;
금단의 영역인 것 같긴하지만, 방금 되는 것을 확인하긴 했습니다...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
그냥 하나의 방법이니 보고 피식 웃고 넘어가주세용~~ ㅋㅋㅋ
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
지금 방법대로 하면 안 되는건가요 ?
상관 없어보이는데..
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
사실 soft delete 의 대가인 것 같아요 ㅋㅋㅋ delete 해줘야 하는 부분에서 연관된 다른 부분들도 신경써야 하는거요
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
근데 @PrePost
썼던 것처럼 @PreRemove
로 할 수 있을지도..?? 해보고 아니면 냅둘게요 ㅎㅎ
라고 생각했는데 JPQL로 삭제할 때는 적용 안되겠네요 ...
사실 지금도 상관없지만 유지보수 측면에서 좀 더 도메인 단에서 로직을 묶을 수 없을까 해서 고민해봤습니당
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
아니면 JPA 이벤트리스너로 해결하는 방법도 있을까 싶은데 이 PR 내용과는 거리가 멀기 때문에 별개로 시도해볼게요!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
좋아연
/// TODO: 2023/10/05 soft delete를 @Query로 구현하면서, pinCount 반영을 통합할 수 없음 | ||
pin.decrementTopicPinCount(); | ||
pinRepository.deleteById(pin.getId()); | ||
/// TODO: 2023/10/05 pinImage는? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
pin image 도 연계적으로 지워줘야 하겠군요....
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
soft delete 가 참 산이 많네요
@@ -31,6 +30,7 @@ public void validateMember(Long memberId) { | |||
} | |||
} | |||
|
|||
// TODO 테스트가 필요하긴 한데, MemberQueryService와 너무 중복되는 내용이다. 엔티티 테스트로 중복을 없앨 수 있으면 좋겠다. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
오우 조금 더 자세하게 말씀해주실 수 있을까요
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
언젠가 MemberQueryService
의 스펙이 바뀔수도 혹은 AuthService
의 스펙이 바뀔 수도 있을 것 같은데요.
그런 의미에서, 중복되는 테스트라고 할지라도 수행하는 것이 좋지 않을까요 ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
맞아요 근데 AuthService 의존성 문제때문에 귀찮아서... + 서비스 단에서 테스트하다보니 발생하는 중복이 많은 것 같아서요. (이건 저희 테스트 코드 전반적인 문제인 것 같아요)
더 작은 단위에서 테스트하면 좋을텐데 엔티티 테스트 해보려니 TestEntityManager 잔뜩 써야 할 것 같아서 일단 안했습니다.
테스트 추가할게용 (왜 여태 테스트 없었죠? 😄)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
허허허허
import java.util.Optional; | ||
import org.springframework.data.jpa.repository.JpaRepository; | ||
|
||
public interface BookmarkRepository extends JpaRepository<Bookmark, Long> { | ||
|
||
boolean existsByMemberIdAndTopicId(Long memberId, Long topicId); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
이건 쥬니 글에서 보았듯 @query 어노테이션이 동반되지 않으면 짜피 clearAutomatically 가 동작하지 않으니까 빼신게 맞나요 ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
코멘트 위치가 잘못된듯요
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
또잉또잉 클릭 잘못했어연 바로 아래줄일듯 허허허
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
맞아요!
public void updateStatus(Status status) { | ||
memberInfo = memberInfo.createUpdatedMemberInfo(status); | ||
} | ||
|
||
public void addTopic(Topic topic) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
형태를 통일해주셨군요 굳
.orElseThrow( | ||
() -> new NoSuchElementException("findCreatorByAuthMember; member not found; id=" + memberId)); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
.orElseThrow(
() -> new NoSuchElementException("findCreatorByAuthMember; member not found; id=" + memberId)
);
도 괜찮아보입니다 ^.^
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
반영할게용
pinRepository.deleteAllByTopicId(topicId); | ||
/// TODO: 2023/10/05 topic의 pinCount는? | ||
topicRepository.deleteById(topicId); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
soft delete 의 대가인 것 같기도..
createAndSaveTopic("준팍의 또간집", 2), | ||
createAndSaveTopic("도이의 또간집", 3), | ||
createAndSaveTopic("패트릭의 또간집", 4) | ||
); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
왜 저는 안 넣어주시죠?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
아 ㅋㅋ 나도 없네
이 아래에 있는 코드 리뷰 안함 ㅂ2
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋ 귀요미 ㅎㅎ
for (int i = 0; i < deleteCounts; i++) { | ||
Pin delete = topic.getPins().get(i); | ||
delete.decrementTopicPinCount(); | ||
pinRepository.deleteById(delete.getId()); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
update pin p, topic t
set p.is_deleted = true, t.pin_count = t.pin_count - 1
where p.id = "삭제하려는 pin id" AND t.id = p.topic_id;
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
역시 SQL 천재시네요
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
반영안할거잖아요!
PinImage deletedPinImage = pinImageRepository.findById(pinImage.getId()).get(); | ||
|
||
assertThat(deletedPinImage.isDeleted()).isTrue(); | ||
assertThat(pinImageRepository.findById(pinImage.getId())).isEmpty(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
바로 위 테스트의 then 절과 해당 테스트의 then 절의 삭제 유무 확인 방식이 조금 다르네요!
킹시 의도하신걸까요 ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
바로 위 테스트가 뭘까요 ? existById와의 차이라면 pinImage는 List라서 이렇게 했습니다 !
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
글 헛 군 요!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
도이 고생 많았어요 !!!
TODO 부분에 의견도 달아두었고, 코드 관련해서 제안드리는 부분이 있어서 RC 하겠습니당.
permissionRepository.deleteAllByMemberId(memberId); | ||
atlasRepository.deleteAllByMemberId(memberId); | ||
bookmarkRepository.deleteAllByMemberId(memberId); | ||
entityManager.flush(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
사실 저도 entityManager
가 존재한다는게 거슬리긴 해요.
준팍이 말씀해주신
entityManager를 주입받을 필요없이 repository에서 flush하는 건 어떨까요??
이 부분은 별도의 설정하지 않아도 된다는 의미일까요 ?
아마, 테스트 코드 구성을 잘못해서 발생한 문제를 해결하기 위해 위와같은 구조를 갖게 된 걸로 알고있어요. (내가 짬 ㅋ)
테스트 코드에서 //given
에서 데이터를 세팅해주는 작업과 같은 트랜잭션으로 묶이기 때문에 flush
를 강제로 호출해주지 않으면 수정 관련 쿼리가 쓰기 지연 저장소에 저장되었다가, 트랜잭션이 커밋되기 직전에 데이터베이스로 쿼리를 날라가게 되요.
어떻게 해결 할 수 있다는 의미인지 궁금합니다 !
Pin pin = pinRepository.findById(pinId) | ||
.orElseThrow(() -> new PinNotFoundException(PIN_NOT_FOUND, pinId)); | ||
|
||
/// TODO: 2023/10/05 soft delete를 @Query로 구현하면서, pinCount 반영을 통합할 수 없음 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
지금 방법대로 하면 안 되는건가요 ?
상관 없어보이는데..
@@ -31,6 +30,7 @@ public void validateMember(Long memberId) { | |||
} | |||
} | |||
|
|||
// TODO 테스트가 필요하긴 한데, MemberQueryService와 너무 중복되는 내용이다. 엔티티 테스트로 중복을 없앨 수 있으면 좋겠다. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
언젠가 MemberQueryService
의 스펙이 바뀔수도 혹은 AuthService
의 스펙이 바뀔 수도 있을 것 같은데요.
그런 의미에서, 중복되는 테스트라고 할지라도 수행하는 것이 좋지 않을까요 ?
import java.util.Optional; | ||
import org.springframework.data.jpa.repository.JpaRepository; | ||
|
||
public interface BookmarkRepository extends JpaRepository<Bookmark, Long> { | ||
|
||
boolean existsByMemberIdAndTopicId(Long memberId, Long topicId); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
코멘트 위치가 잘못된듯요
|
||
public interface BookmarkRepository extends JpaRepository<Bookmark, Long> { | ||
|
||
boolean existsByMemberIdAndTopicId(Long memberId, Long topicId); | ||
|
||
@Modifying(clearAutomatically = true) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
이 부분 JPQL로 해결해야하는데... 도이꺼 PR 머지되면 브랜치 따서 해결할게요.
잊지말자 !!!!!!!!!!!!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
여기다가 제가 단 거 였는데 ㅋㅋㅋㅋ
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Service에서 EntityManager 불러오는 대신 JPQL로 바꾸고 @Modifying
다시 적용한다는거죵 ?
아주 좋습니다아
@@ -102,6 +104,10 @@ public void updatePinInfo(String name, String description) { | |||
pinInfo = PinInfo.of(name, description); | |||
} | |||
|
|||
public void decrementTopicPinCount() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
decrement
는 명사 아닌가요 ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
엥 맞아요 왜 저렇게 썼을까요 ? 영어 천재시네요 . 고칠게용
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
천재아닌데요!
/// TODO: 2023/10/05 topic의 pinCount는? | ||
topicRepository.deleteById(topicId); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pin 자체가 hard-delete 된게 아니다 보니, pinCount 값은 그대로 두어도 무방할 것 같은데요 ?
pin이 삭제될 때에만 topic의 pinCount 값을 신경쓰고요 !
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
topic 살면 pin 도 다 다시 살아나니까?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
저도 똑같이 생각해서 적용 안했는데 주석이 남아있었네요! 지울게욥
@@ -147,6 +149,10 @@ public void removeImage() { | |||
this.topicInfo = topicInfo.removeImage(); | |||
} | |||
|
|||
public void decrementPinCount() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
명사명사명사명사명사명사명사명사명사명사명사명사명사명사명사명사명사명사명사명사명사명사명사명사명사명사명사명사명사명사명사명사명사명사명사명사명사명사명사명사명사명사
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇ
createAndSaveTopic("준팍의 또간집", 2), | ||
createAndSaveTopic("도이의 또간집", 3), | ||
createAndSaveTopic("패트릭의 또간집", 4) | ||
); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
아 ㅋㅋ 나도 없네
이 아래에 있는 코드 리뷰 안함 ㅂ2
말씀해주신 사항들 반영했습니다 ! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
도이 넘흐넘흐 고생하셨어요!
Approve 드립니다!
Pin pin = pinRepository.findById(pinId) | ||
.orElseThrow(() -> new PinNotFoundException(PIN_NOT_FOUND, pinId)); | ||
|
||
/// TODO: 2023/10/05 soft delete를 @Query로 구현하면서, pinCount 반영을 통합할 수 없음 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
좋아연
permissionRepository.deleteAllByTopicId(topicId); | ||
permissionRepository.flush(); | ||
atlasRepository.deleteAllByTopicId(topicId); | ||
atlasRepository.flush(); | ||
bookmarkRepository.deleteAllByTopicId(topicId); | ||
bookmarkRepository.flush(); | ||
pinImageRepository.deleteAllByPinIds(pinIds); | ||
pinRepository.deleteAllByTopicId(topicId); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
하나의 repository 가 flush 의무를 갖는 것이 애매하기 때문에 모든 repository 가 flush 를 호출할 수 있도록 하셨군요! 좋습니다.
그리고, 이 부분은 추후에 개선할 수 있으면 개선하도록 해보죠! (명시적으로 flush 호출 안해보도록)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
앗 저 각각 해야 하는줄알았어요...ㅎㅎ 근데 매튜 말대로 곧 사라질 내용인걸로!
.isInstanceOf(UnauthorizedException.class); | ||
} | ||
|
||
@Transactional(propagation = Propagation.REQUIRES_NEW) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
야무지게 쓰셨네요
@@ -56,8 +56,7 @@ public ResponseEntity<TopicAccessDetailResponse> findTopicAccessDetailByTopicId( | |||
return ResponseEntity.ok(response); | |||
} | |||
|
|||
// TODO 이 API를 쓰는 곳이 있나? + 결국 특정 회원을 조회하는 건데 어떤 API인지 알기 어렵다.. | |||
// 회원 정보 조회는 /members 에서 하는 걸로 충분하지 않나? 재사용성이 떨어진다. 테스트의 DisplayName도 매칭이 안된다. | |||
@Deprecated(since = "2023.10.06") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1
작업 대상
Repository 메서드에
IsDeletedFalse
를 붙여 조회 기능에 soft delete을 반영함에 따라지연 로딩으로 정보를 조회하는 경우, 삭제된 토픽/핀도 조회하게 되는 문제가 있었습니다.
이를 해결하기 위한 방법 중 엔티티에
@Where
을 적용하는 것을 선택했습니다.stream, filter는 지연로딩인 모든 연관 관계의 getter에 대해 이를 적용해주어야 한다는 문제가 있기 때문입니다.
빠른 적용이 필요한 상황에서도 오히려 시간이 더 오래 걸릴 수 있습니다.
또, 그에 비해
@Where
적용 시, 수정이 필요한 대부분은 관리자 기능 및 테스트 코드인 데에 비해새로 엔티티가 추가될 때마다/연관관계가 변경될때마다 getter를 수정하는 작업을 하기에는 유지보수성도 떨어진다고 판단했습니다.
고려해야 할 연관관계 (테스트 작성)
작업 내용
📄 작업 내용
추가 작업
Pin을 삭제할 경우 Topic의 pinCount 컬럼을 업데이트하는 로직이 없는 것을 발견하여 이를 추가했습니다. (해당 커밋)
🙋🏻 주의 사항
일종의 버그 해결이기 때문에 Hotfix라고 생각하지만, 개발 서버에도 먼저 반영될 사안이라고 생각해 develop-BE로 PR 보냅니다.
개발서버 배포 후 바로 운영서버 배포하면 될 것 같습니다.
스크린샷
📎 관련 이슈
closed #540
레퍼런스