From 041cac83270eb9922c1e399a2fe4f07a0a541d4e Mon Sep 17 00:00:00 2001 From: hong seokho Date: Tue, 4 Jun 2024 23:25:15 +0900 Subject: [PATCH] =?UTF-8?q?fix=20:=20=EB=9D=BD=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 현재 상황에선 오버 엔지니어링인 것으로 예상되어 락 제거 --- .../domain/friend/entity/FriendInvite.java | 5 ++-- .../friend_invite/FriendInviteRepository.java | 15 +++-------- .../service/command/FriendCommandService.java | 22 +++++++++------- .../core/domain/member/entity/Member.java | 26 ------------------- .../global/error/GlobalExceptionHandler.java | 12 +++++++++ .../exception/InternalServerException.java | 10 +++++++ 6 files changed, 40 insertions(+), 50 deletions(-) create mode 100644 backend/core/src/main/java/site/timecapsulearchive/core/global/error/exception/InternalServerException.java diff --git a/backend/core/src/main/java/site/timecapsulearchive/core/domain/friend/entity/FriendInvite.java b/backend/core/src/main/java/site/timecapsulearchive/core/domain/friend/entity/FriendInvite.java index 9a2ce2f19..a31f7b4ae 100644 --- a/backend/core/src/main/java/site/timecapsulearchive/core/domain/friend/entity/FriendInvite.java +++ b/backend/core/src/main/java/site/timecapsulearchive/core/domain/friend/entity/FriendInvite.java @@ -1,5 +1,6 @@ package site.timecapsulearchive.core.domain.friend.entity; +import jakarta.persistence.CascadeType; import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.FetchType; @@ -26,11 +27,11 @@ public class FriendInvite extends BaseEntity { @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; - @ManyToOne(fetch = FetchType.LAZY) + @ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.PERSIST) @JoinColumn(name = "owner_id", nullable = false) private Member owner; - @ManyToOne(fetch = FetchType.LAZY) + @ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.PERSIST) @JoinColumn(name = "friend_id", nullable = false) private Member friend; diff --git a/backend/core/src/main/java/site/timecapsulearchive/core/domain/friend/repository/friend_invite/FriendInviteRepository.java b/backend/core/src/main/java/site/timecapsulearchive/core/domain/friend/repository/friend_invite/FriendInviteRepository.java index 18f7bcabe..bc9340551 100644 --- a/backend/core/src/main/java/site/timecapsulearchive/core/domain/friend/repository/friend_invite/FriendInviteRepository.java +++ b/backend/core/src/main/java/site/timecapsulearchive/core/domain/friend/repository/friend_invite/FriendInviteRepository.java @@ -1,12 +1,7 @@ package site.timecapsulearchive.core.domain.friend.repository.friend_invite; -import jakarta.persistence.LockModeType; -import jakarta.persistence.QueryHint; -import java.util.List; import java.util.Optional; -import org.springframework.data.jpa.repository.Lock; import org.springframework.data.jpa.repository.Query; -import org.springframework.data.jpa.repository.QueryHints; import org.springframework.data.repository.Repository; import org.springframework.data.repository.query.Param; import site.timecapsulearchive.core.domain.friend.entity.FriendInvite; @@ -18,8 +13,6 @@ public interface FriendInviteRepository extends Repository, void delete(FriendInvite friendInvite); - @Lock(LockModeType.PESSIMISTIC_WRITE) - @QueryHints({@QueryHint(name = "jakarta.persistence.lock.timeout", value = "3000")}) Optional findFriendSendingInviteForUpdateByOwnerIdAndFriendId(Long memberId, Long friendId); @@ -28,12 +21,10 @@ Optional findFriendSendingInviteForUpdateByOwnerIdAndFriendId(Long from FriendInvite fi join fetch fi.owner join fetch fi.friend - where fi.owner.id =:friendId and fi.friend.id =:memberId + where fi.owner.id =:ownerId and fi.friend.id =:friendId """) - @Lock(LockModeType.PESSIMISTIC_WRITE) - @QueryHints({@QueryHint(name = "jakarta.persistence.lock.timeout", value = "3000")}) - Optional findFriendReceptionInviteForUpdateByOwnerIdAndFriendId( - @Param(value = "memberId") Long memberId, + Optional findFriendReceivingInviteForUpdateByOwnerIdAndFriendId( + @Param(value = "ownerId") Long ownerId, @Param(value = "friendId") Long friendId ); } diff --git a/backend/core/src/main/java/site/timecapsulearchive/core/domain/friend/service/command/FriendCommandService.java b/backend/core/src/main/java/site/timecapsulearchive/core/domain/friend/service/command/FriendCommandService.java index 8c4d885a4..15a0455ad 100644 --- a/backend/core/src/main/java/site/timecapsulearchive/core/domain/friend/service/command/FriendCommandService.java +++ b/backend/core/src/main/java/site/timecapsulearchive/core/domain/friend/service/command/FriendCommandService.java @@ -1,5 +1,6 @@ package site.timecapsulearchive.core.domain.friend.service.command; +import jakarta.persistence.OptimisticLockException; import java.util.List; import java.util.Optional; import lombok.RequiredArgsConstructor; @@ -21,7 +22,7 @@ import site.timecapsulearchive.core.domain.member.entity.Member; import site.timecapsulearchive.core.domain.member.exception.MemberNotFoundException; import site.timecapsulearchive.core.domain.member.repository.MemberRepository; -import site.timecapsulearchive.core.global.error.ErrorCode; +import site.timecapsulearchive.core.global.error.exception.InternalServerException; import site.timecapsulearchive.core.infra.queue.manager.SocialNotificationManager; @Slf4j @@ -115,12 +116,12 @@ private void validateTwoWayAndDuplicateInvite(final Long memberId, final Long fr } - public void acceptFriend(final Long memberId, final Long friendId) { - validateSelfFriendOperation(memberId, friendId); + public void acceptFriend(final Long memberId, final Long ownerId) { + validateSelfFriendOperation(memberId, ownerId); final String ownerNickname = transactionTemplate.execute(status -> { - FriendInvite friendInvite = friendInviteRepository.findFriendReceptionInviteForUpdateByOwnerIdAndFriendId( - memberId, friendId) + FriendInvite friendInvite = friendInviteRepository.findFriendReceivingInviteForUpdateByOwnerIdAndFriendId( + ownerId, memberId) .orElseThrow(FriendInviteNotFoundException::new); final MemberFriend ownerRelation = friendInvite.ownerRelation(); @@ -128,20 +129,21 @@ public void acceptFriend(final Long memberId, final Long friendId) { memberFriendRepository.save(ownerRelation); memberFriendRepository.save(friendRelation); + friendInviteRepository.delete(friendInvite); return ownerRelation.getOwnerNickname(); }); - socialNotificationManager.sendFriendAcceptMessage(ownerNickname, friendId); + socialNotificationManager.sendFriendAcceptMessage(ownerNickname, ownerId); } @Transactional - public void denyRequestFriend(final Long memberId, final Long friendId) { - validateSelfFriendOperation(memberId, friendId); + public void denyRequestFriend(final Long memberId, final Long ownerId) { + validateSelfFriendOperation(memberId, ownerId); - FriendInvite friendInvite = friendInviteRepository.findFriendReceptionInviteForUpdateByOwnerIdAndFriendId( - memberId, friendId) + FriendInvite friendInvite = friendInviteRepository.findFriendReceivingInviteForUpdateByOwnerIdAndFriendId( + ownerId, memberId) .orElseThrow(FriendInviteNotFoundException::new); friendInviteRepository.delete(friendInvite); diff --git a/backend/core/src/main/java/site/timecapsulearchive/core/domain/member/entity/Member.java b/backend/core/src/main/java/site/timecapsulearchive/core/domain/member/entity/Member.java index e94e51515..0b179f065 100644 --- a/backend/core/src/main/java/site/timecapsulearchive/core/domain/member/entity/Member.java +++ b/backend/core/src/main/java/site/timecapsulearchive/core/domain/member/entity/Member.java @@ -1,6 +1,5 @@ package site.timecapsulearchive.core.domain.member.entity; -import jakarta.persistence.CascadeType; import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.EnumType; @@ -8,19 +7,12 @@ import jakarta.persistence.GeneratedValue; import jakarta.persistence.GenerationType; import jakarta.persistence.Id; -import jakarta.persistence.OneToMany; import jakarta.persistence.Table; import jakarta.validation.constraints.Email; -import java.util.List; import lombok.AccessLevel; import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; -import site.timecapsulearchive.core.domain.capsule.entity.Capsule; -import site.timecapsulearchive.core.domain.friend.entity.FriendInvite; -import site.timecapsulearchive.core.domain.friend.entity.MemberFriend; -import site.timecapsulearchive.core.domain.history.entity.History; -import site.timecapsulearchive.core.domain.member_group.entity.MemberGroup; import site.timecapsulearchive.core.global.entity.BaseEntity; import site.timecapsulearchive.core.global.util.NullCheck; import site.timecapsulearchive.core.global.util.TagGenerator; @@ -74,24 +66,6 @@ public class Member extends BaseEntity { @Column(name = "tag", nullable = false, unique = true) private String tag; - @OneToMany(mappedBy = "member", cascade = CascadeType.ALL, orphanRemoval = true) - private List capsules; - - @OneToMany(mappedBy = "member", cascade = CascadeType.ALL, orphanRemoval = true) - private List groups; - - @OneToMany(mappedBy = "friend", cascade = CascadeType.ALL, orphanRemoval = true) - private List friends; - - @OneToMany(mappedBy = "owner", cascade = CascadeType.ALL, orphanRemoval = true) - private List friendsRequests; - - @OneToMany(mappedBy = "friend", cascade = CascadeType.ALL, orphanRemoval = true) - private List notifications; - - @OneToMany(mappedBy = "member", cascade = CascadeType.ALL, orphanRemoval = true) - private List histories; - @Builder private Member(String profileUrl, String nickname, SocialType socialType, String email, String authId, String password, String tag, byte[] phone, byte[] phone_hash) { diff --git a/backend/core/src/main/java/site/timecapsulearchive/core/global/error/GlobalExceptionHandler.java b/backend/core/src/main/java/site/timecapsulearchive/core/global/error/GlobalExceptionHandler.java index 459f36da8..d45f86f38 100644 --- a/backend/core/src/main/java/site/timecapsulearchive/core/global/error/GlobalExceptionHandler.java +++ b/backend/core/src/main/java/site/timecapsulearchive/core/global/error/GlobalExceptionHandler.java @@ -19,6 +19,7 @@ import org.springframework.web.bind.annotation.RestControllerAdvice; import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException; import site.timecapsulearchive.core.global.error.exception.BusinessException; +import site.timecapsulearchive.core.global.error.exception.InternalServerException; import site.timecapsulearchive.core.global.error.exception.NullCheckValidateException; import site.timecapsulearchive.core.infra.sms.exception.ExternalApiException; @@ -47,6 +48,17 @@ protected ResponseEntity handleBusinessException(final BusinessEx .body(errorResponse); } + @ExceptionHandler(InternalServerException.class) + protected ResponseEntity handleInternalServerException(final InternalServerException e) { + log.error(e.getMessage(), e); + + ErrorCode errorCode = INTERNAL_SERVER_ERROR; + final ErrorResponse errorResponse = ErrorResponse.fromErrorCode(errorCode); + + return ResponseEntity.status(errorCode.getStatus()) + .body(errorResponse); + } + @ExceptionHandler(MethodArgumentNotValidException.class) protected ResponseEntity handleRequestArgumentNotValidException( MethodArgumentNotValidException e diff --git a/backend/core/src/main/java/site/timecapsulearchive/core/global/error/exception/InternalServerException.java b/backend/core/src/main/java/site/timecapsulearchive/core/global/error/exception/InternalServerException.java new file mode 100644 index 000000000..8f8909972 --- /dev/null +++ b/backend/core/src/main/java/site/timecapsulearchive/core/global/error/exception/InternalServerException.java @@ -0,0 +1,10 @@ +package site.timecapsulearchive.core.global.error.exception; + +import site.timecapsulearchive.core.global.error.ErrorCode; + +public class InternalServerException extends RuntimeException { + + public InternalServerException(Throwable e) { + super(ErrorCode.INTERNAL_SERVER_ERROR.getMessage(), e); + } +}