Skip to content
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

Merged
merged 16 commits into from
Oct 6, 2023
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.mapbefine.mapbefine.admin.application;

import static com.mapbefine.mapbefine.pin.exception.PinErrorCode.PIN_NOT_FOUND;
import static com.mapbefine.mapbefine.topic.exception.TopicErrorCode.TOPIC_NOT_FOUND;

import com.mapbefine.mapbefine.atlas.domain.AtlasRepository;
Expand All @@ -11,19 +12,23 @@
import com.mapbefine.mapbefine.pin.domain.Pin;
import com.mapbefine.mapbefine.pin.domain.PinImageRepository;
import com.mapbefine.mapbefine.pin.domain.PinRepository;
import com.mapbefine.mapbefine.pin.exception.PinException.PinNotFoundException;
import com.mapbefine.mapbefine.topic.domain.Topic;
import com.mapbefine.mapbefine.topic.domain.TopicRepository;
import com.mapbefine.mapbefine.topic.exception.TopicException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import jakarta.persistence.EntityManager;
import jakarta.persistence.PersistenceContext;
import java.util.List;
import java.util.NoSuchElementException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
@Transactional
public class AdminCommandService {

@PersistenceContext
private EntityManager entityManager;
private final MemberRepository memberRepository;
private final TopicRepository topicRepository;
private final PinRepository pinRepository;
Expand Down Expand Up @@ -61,12 +66,13 @@ private void deleteAllRelatedMember(Member member) {
List<Long> pinIds = extractPinIdsByMember(member);
Long memberId = member.getId();

pinImageRepository.deleteAllByPinIds(pinIds);
topicRepository.deleteAllByMemberId(memberId);
pinRepository.deleteAllByMemberId(memberId);
permissionRepository.deleteAllByMemberId(memberId);
atlasRepository.deleteAllByMemberId(memberId);
bookmarkRepository.deleteAllByMemberId(memberId);
entityManager.flush();
Copy link
Collaborator

@junpakPark junpakPark Oct 5, 2023

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하는 건 어떨까요??

Copy link
Collaborator

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 가 가져가야 하는지를 정하는 것도 굉장히 애매한 부분인 것 같기도 하네요.

다들 어떻게 생각하시나요?

Copy link
Collaborator

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를 강제로 호출해주지 않으면 수정 관련 쿼리가 쓰기 지연 저장소에 저장되었다가, 트랜잭션이 커밋되기 직전에 데이터베이스로 쿼리를 날라가게 되요.
어떻게 해결 할 수 있다는 의미인지 궁금합니다 !

Copy link
Collaborator Author

@yoondgu yoondgu Oct 5, 2023

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할 경우 아래와 같은 순서로 동작하는 것 아닐까요?

  1. hard delete 메서드를 통해 해당 id를 가진 엔티티를 영속성 컨텍스트에서 제거한다.
  2. soft delete 메서드를 통해 update를 호출하면서, 연관된 엔티티들이 모두 영속화된다.
    -> (1)에서 delete 해도, 2에서 조회할 때 함께 불러와지는 permission, atlas, bookmark까지 다시 영속화된다.
  3. 그래서 한 번에 flush할 때 delete 쿼리가 나가지 않는다.

그래서 (1)과 (2) 사이에 직접 flush를 해야 한다고 생각했어요.
제가 아직 헷갈려서 정리하다보니 길어졌네요.. ㅎㅎ 그래도 참고차 남깁니다.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

아니 제가 화면 새로고침을 안해서 쥬니 댓글 지금봤네용 하핫

Copy link
Collaborator

@junpakPark junpakPark Oct 5, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@cpot5620 @yoondgu

image

아 저는 flush를 별도로 설정하지 말라는 의미는 아니었구요!
위에 보이는 메서드를 사용하자는 의미였습니다 ㅎㅎ
이 메서드를 사용하면 entityManager의 flush를 사용한것과 동일하게 작동한다고 하네요 ㅎㅎ

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

GPT 센세의 첨언...

image

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

세 레포지터리 중 어떤 것을 써도 동일하게 동작할텐데
매튜 말대로 뭐 써야될지 조금 고민되긴 하겠네요 ㅋㅋ

Copy link
Collaborator Author

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 으로 해결하는 건 어떠세요?
쥬니가 쓴 기술 블로그 참고

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

좋습니다 ㅎㅎ

pinImageRepository.deleteAllByPinIds(pinIds);
pinRepository.deleteAllByMemberId(memberId);
topicRepository.deleteAllByMemberId(memberId);
}

private Member findMemberById(Long id) {
Expand All @@ -91,12 +97,18 @@ public void deleteTopicImage(Long topicId) {
}

private Topic findTopicById(Long topicId) {
return topicRepository.findByIdAndIsDeletedFalse(topicId)
return topicRepository.findById(topicId)
.orElseThrow(() -> new TopicException.TopicNotFoundException(TOPIC_NOT_FOUND, List.of(topicId)));
}

public void deletePin(Long pinId) {
pinRepository.deleteById(pinId);
Pin pin = pinRepository.findById(pinId)
.orElseThrow(() -> new PinNotFoundException(PIN_NOT_FOUND, pinId));

/// TODO: 2023/10/05 soft delete를 @Query로 구현하면서, pinCount 반영을 통합할 수 없음
Copy link
Collaborator

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;

금단의 영역인 것 같긴하지만, 방금 되는 것을 확인하긴 했습니다...

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

그냥 하나의 방법이니 보고 피식 웃고 넘어가주세용~~ ㅋㅋㅋ

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

지금 방법대로 하면 안 되는건가요 ?
상관 없어보이는데..

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

사실 soft delete 의 대가인 것 같아요 ㅋㅋㅋ delete 해줘야 하는 부분에서 연관된 다른 부분들도 신경써야 하는거요

Copy link
Collaborator Author

@yoondgu yoondgu Oct 5, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

근데 @PrePost 썼던 것처럼 @PreRemove로 할 수 있을지도..?? 해보고 아니면 냅둘게요 ㅎㅎ
라고 생각했는데 JPQL로 삭제할 때는 적용 안되겠네요 ...
사실 지금도 상관없지만 유지보수 측면에서 좀 더 도메인 단에서 로직을 묶을 수 없을까 해서 고민해봤습니당

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

아니면 JPA 이벤트리스너로 해결하는 방법도 있을까 싶은데 이 PR 내용과는 거리가 멀기 때문에 별개로 시도해볼게요!

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

좋아연

pin.decrementTopicPinCount();
pinRepository.deleteById(pin.getId());
/// TODO: 2023/10/05 pinImage는?
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pin image 도 연계적으로 지워줘야 하겠군요....

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

soft delete 가 참 산이 많네요

}

public void deletePinImage(Long pinImageId) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,10 @@
import com.mapbefine.mapbefine.member.domain.MemberRepository;
import com.mapbefine.mapbefine.topic.domain.Topic;
import com.mapbefine.mapbefine.topic.domain.TopicRepository;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.NoSuchElementException;
import java.util.Objects;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
@Transactional
Expand Down Expand Up @@ -73,7 +72,7 @@ private boolean isTopicAlreadyAdded(Long topicId, Long memberId) {
}

private Topic findTopicById(Long topicId) {
return topicRepository.findByIdAndIsDeletedFalse(topicId)
return topicRepository.findById(topicId)
.orElseThrow(() -> new AtlasBadRequestException(ILLEGAL_TOPIC_ID));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
import com.mapbefine.mapbefine.topic.domain.Topic;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

Expand All @@ -31,6 +30,7 @@ public void validateMember(Long memberId) {
}
}

// TODO 테스트가 필요하긴 한데, MemberQueryService와 너무 중복되는 내용이다. 엔티티 테스트로 중복을 없앨 수 있으면 좋겠다.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

오우 조금 더 자세하게 말씀해주실 수 있을까요

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

언젠가 MemberQueryService의 스펙이 바뀔수도 혹은 AuthService의 스펙이 바뀔 수도 있을 것 같은데요.
그런 의미에서, 중복되는 테스트라고 할지라도 수행하는 것이 좋지 않을까요 ?

Copy link
Collaborator Author

@yoondgu yoondgu Oct 5, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

맞아요 근데 AuthService 의존성 문제때문에 귀찮아서... + 서비스 단에서 테스트하다보니 발생하는 중복이 많은 것 같아서요. (이건 저희 테스트 코드 전반적인 문제인 것 같아요)

더 작은 단위에서 테스트하면 좋을텐데 엔티티 테스트 해보려니 TestEntityManager 잔뜩 써야 할 것 같아서 일단 안했습니다.
테스트 추가할게용 (왜 여태 테스트 없었죠? 😄)

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

허허허허

public AuthMember findAuthMemberByMemberId(Long memberId) {
return memberRepository.findById(memberId)
.map(this::convertToAuthMember)
Expand Down Expand Up @@ -63,15 +63,4 @@ private List<Long> getCreatedTopics(Member member) {
.toList();
}

public boolean isAdmin(Long memberId) {
if (Objects.isNull(memberId)) {
return false;
}

Optional<Member> member = memberRepository.findById(memberId);

return member.map(Member::isAdmin)
.orElse(false);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,10 @@
import com.mapbefine.mapbefine.member.domain.MemberRepository;
import com.mapbefine.mapbefine.topic.domain.Topic;
import com.mapbefine.mapbefine.topic.domain.TopicRepository;
import java.util.NoSuchElementException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.NoSuchElementException;

@Service
@Transactional
public class BookmarkCommandService {
Expand Down Expand Up @@ -53,7 +52,7 @@ public Long addTopicInBookmark(AuthMember authMember, Long topicId) {
}

private Topic getTopicById(Long topicId) {
return topicRepository.findByIdAndIsDeletedFalse(topicId)
return topicRepository.findById(topicId)
.orElseThrow(() -> new BookmarkBadRequestException(ILLEGAL_TOPIC_ID));
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,12 @@
package com.mapbefine.mapbefine.bookmark.domain;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;

import java.util.Optional;
import org.springframework.data.jpa.repository.JpaRepository;

public interface BookmarkRepository extends JpaRepository<Bookmark, Long> {

boolean existsByMemberIdAndTopicId(Long memberId, Long topicId);

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이건 쥬니 글에서 보았듯 @query 어노테이션이 동반되지 않으면 짜피 clearAutomatically 가 동작하지 않으니까 빼신게 맞나요 ?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

코멘트 위치가 잘못된듯요

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

또잉또잉 클릭 잘못했어연 바로 아래줄일듯 허허허

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

맞아요!

@Modifying(clearAutomatically = true)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이 부분 JPQL로 해결해야하는데... 도이꺼 PR 머지되면 브랜치 따서 해결할게요.

잊지말자 !!!!!!!!!!!!

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

여기다가 제가 단 거 였는데 ㅋㅋㅋㅋ

Copy link
Collaborator Author

@yoondgu yoondgu Oct 5, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Service에서 EntityManager 불러오는 대신 JPQL로 바꾸고 @Modifying 다시 적용한다는거죵 ?
아주 좋습니다아

void deleteAllByMemberId(Long memberId);

Optional<Bookmark> findByMemberIdAndTopicId(Long memberId, Long topicId);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public void updateInfoById(AuthMember authMember, MemberUpdateRequest request) {

validateNicknameDuplicated(nickName);

member.update(nickName);
member.updateNickName(nickName);
}

private Member findMemberById(Long memberId) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ public List<MemberResponse> findAll() {
public List<TopicResponse> findAllTopicsInBookmark(AuthMember authMember) {
Member member = findMemberById(authMember.getMemberId());

List<Topic> bookMarkedTopics = topicRepository.findTopicsByBookmarksMemberIdAndIsDeletedFalse(
List<Topic> bookMarkedTopics = topicRepository.findTopicsByBookmarksMemberId(
authMember.getMemberId());
return bookMarkedTopics.stream()
.map(topic -> TopicResponse.from(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,12 +104,16 @@ private static String createNicknameSuffix() {
.substring(0, DEFAULT_NICKNAME_SUFFIX_LENGTH);
}

public void update(
public void updateNickName(
String nickName
) {
memberInfo = memberInfo.createUpdatedMemberInfo(nickName);
}

public void updateStatus(Status status) {
memberInfo = memberInfo.createUpdatedMemberInfo(status);
}

public void addTopic(Topic topic) {
Comment on lines +113 to 117
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

형태를 통일해주셨군요 굳

createdTopics.add(topic);
}
Expand Down Expand Up @@ -147,14 +151,4 @@ public List<Topic> getTopicsWithPermissions() {
public boolean isNormalStatus() {
return memberInfo.getStatus() == Status.NORMAL;
}

public void updateStatus(Status status) {
memberInfo = MemberInfo.of(
memberInfo.getNickName(),
memberInfo.getEmail(),
memberInfo.getImageUrl(),
memberInfo.getRole(),
status
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,11 @@ public MemberInfo createUpdatedMemberInfo(String nickName) {
return MemberInfo.of(nickName, this.email, this.imageUrl.getImageUrl(), this.role, this.status);
}

public MemberInfo createUpdatedMemberInfo(Status status) {

return MemberInfo.of(this.nickName, this.email, this.imageUrl.getImageUrl(), this.role, status);
}

public String getImageUrl() {
return imageUrl.getImageUrl();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,10 @@
import com.mapbefine.mapbefine.permission.exception.PermissionException.PermissionForbiddenException;
import com.mapbefine.mapbefine.topic.domain.Topic;
import com.mapbefine.mapbefine.topic.domain.TopicRepository;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Objects;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
@Transactional
Expand Down Expand Up @@ -78,7 +77,7 @@ private boolean isNotSelfMember(AuthMember authMember, Member member) {

private Topic findTopic(PermissionRequest request) {
Long topicId = request.topicId();
return topicRepository.findByIdAndIsDeletedFalse(topicId)
return topicRepository.findById(topicId)
.orElseThrow(() -> new PermissionBadRequestException(ILLEGAL_TOPIC_ID, topicId));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,10 @@
import com.mapbefine.mapbefine.topic.domain.TopicStatus;
import com.mapbefine.mapbefine.topic.exception.TopicErrorCode;
import com.mapbefine.mapbefine.topic.exception.TopicException.TopicNotFoundException;
import java.util.List;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

@Service
@Transactional(readOnly = true)
public class PermissionQueryService {
Expand All @@ -43,7 +42,7 @@ public TopicAccessDetailResponse findTopicAccessDetailById(Long topicId) {
}

private Publicity findTopicPublicityById(Long topicId) {
return topicRepository.findByIdAndIsDeletedFalse(topicId)
return topicRepository.findById(topicId)
.map(Topic::getTopicStatus)
.map(TopicStatus::getPublicity)
.orElseThrow(() -> new TopicNotFoundException(TopicErrorCode.TOPIC_NOT_FOUND, topicId));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,5 @@ public interface PermissionRepository extends JpaRepository<Permission, Long> {
boolean existsByTopicIdAndMemberId(Long topicId, Long memberId);

void deleteAllByMemberId(Long memberId);

}
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,12 @@
import com.mapbefine.mapbefine.topic.domain.Topic;
import com.mapbefine.mapbefine.topic.domain.TopicRepository;
import com.mapbefine.mapbefine.topic.exception.TopicException.TopicBadRequestException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.util.List;
import java.util.NoSuchElementException;
import java.util.Objects;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

@Transactional
@Service
Expand Down Expand Up @@ -100,7 +99,7 @@ private Topic findTopic(Long topicId) {
if (Objects.isNull(topicId)) {
throw new TopicBadRequestException(ILLEGAL_TOPIC_ID);
}
return topicRepository.findByIdAndIsDeletedFalse(topicId)
return topicRepository.findById(topicId)
.orElseThrow(() -> new TopicBadRequestException(ILLEGAL_TOPIC_ID));
}

Expand Down Expand Up @@ -146,7 +145,7 @@ public void update(
}

private Pin findPin(Long pinId) {
return pinRepository.findByIdAndIsDeletedFalse(pinId)
return pinRepository.findById(pinId)
.orElseThrow(() -> new PinBadRequestException(ILLEGAL_PIN_ID));
}

Expand Down Expand Up @@ -182,7 +181,7 @@ public void removeImageById(AuthMember authMember, Long pinImageId) {
}

private PinImage findPinImage(Long pinImageId) {
return pinImageRepository.findByIdAndIsDeletedFalse(pinImageId)
return pinImageRepository.findById(pinImageId)
.orElseThrow(() -> new PinBadRequestException(ILLEGAL_PIN_IMAGE_ID));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,10 @@
import com.mapbefine.mapbefine.pin.exception.PinException.PinForbiddenException;
import com.mapbefine.mapbefine.pin.exception.PinException.PinNotFoundException;
import com.mapbefine.mapbefine.topic.domain.Topic;
import java.util.List;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

@Transactional(readOnly = true)
@Service
public class PinQueryService {
Expand All @@ -27,15 +26,15 @@ public PinQueryService(PinRepository pinRepository) {
}

public List<PinResponse> findAllReadable(AuthMember member) {
return pinRepository.findAllByIsDeletedFalse()
return pinRepository.findAll()
.stream()
.filter(pin -> member.canRead(pin.getTopic()))
.map(PinResponse::from)
.toList();
}

public PinDetailResponse findDetailById(AuthMember member, Long pinId) {
Pin pin = pinRepository.findByIdAndIsDeletedFalse(pinId)
Pin pin = pinRepository.findById(pinId)
.orElseThrow(() -> new PinNotFoundException(PIN_NOT_FOUND, pinId));
validateReadAuth(member, pin.getTopic());

Expand All @@ -51,7 +50,7 @@ private void validateReadAuth(AuthMember member, Topic topic) {
}

public List<PinResponse> findAllPinsByMemberId(AuthMember authMember, Long memberId) {
return pinRepository.findAllByCreatorIdAndIsDeletedFalse(memberId)
return pinRepository.findAllByCreatorId(memberId)
.stream()
.filter(pin -> authMember.canRead(pin.getTopic()))
.map(PinResponse::from)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,12 @@
import lombok.Getter;
import lombok.NoArgsConstructor;
import org.hibernate.annotations.ColumnDefault;
import org.hibernate.annotations.Where;

@Entity
@NoArgsConstructor(access = PROTECTED)
@Getter
@Where(clause = "is_deleted = false")
public class Pin extends BaseTimeEntity {

@Id
Expand Down Expand Up @@ -102,6 +104,10 @@ public void updatePinInfo(String name, String description) {
pinInfo = PinInfo.of(name, description);
}

public void decrementTopicPinCount() {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

decrement는 명사 아닌가요 ?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

엥 맞아요 왜 저렇게 썼을까요 ? 영어 천재시네요 . 고칠게용

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

천재아닌데요!

topic.decrementPinCount();
}

public void copyToTopic(Member creator, Topic topic) {
Pin copiedPin = Pin.createPinAssociatedWithLocationAndTopicAndMember(
pinInfo.getName(),
Expand Down
Loading
Loading