diff --git a/src/main/java/com/divary/domain/logbase/logbook/service/LogBookService.java b/src/main/java/com/divary/domain/logbase/logbook/service/LogBookService.java index d4f8ad7..8d5bd8f 100644 --- a/src/main/java/com/divary/domain/logbase/logbook/service/LogBookService.java +++ b/src/main/java/com/divary/domain/logbase/logbook/service/LogBookService.java @@ -58,11 +58,12 @@ public class LogBookService { .build(); } - @Transactional + @Transactional(readOnly = true) public List getLogBooksByYearAndStatus(int year, SaveStatus status, Long userId) { List logBaseInfoList; + Member member = memberService.findById(userId); if (status == null) { @@ -84,7 +85,7 @@ public List getLogBooksByYearAndStatus(int year, SaveStatu }//연도에 따라, 저장 상태(임시저장,완전저장)에 따라 로그북베이스정보 조회 - @Transactional + @Transactional(readOnly = true) public List getLogBooks(Long userId) { List logBaseInfoList = logBaseInfoRepository.findByMemberId(userId); diff --git a/src/main/java/com/divary/domain/member/service/MemberServiceImpl.java b/src/main/java/com/divary/domain/member/service/MemberServiceImpl.java index 1e1277d..f680897 100644 --- a/src/main/java/com/divary/domain/member/service/MemberServiceImpl.java +++ b/src/main/java/com/divary/domain/member/service/MemberServiceImpl.java @@ -39,6 +39,7 @@ public class MemberServiceImpl implements MemberService { private int gracePeriodDays; @Override + @Transactional(readOnly = true) public Member findMemberByEmail(String email) { return memberRepository.findByEmail(email).orElseThrow(()-> new BusinessException(ErrorCode.EMAIL_NOT_FOUND)); } @@ -52,18 +53,35 @@ public Member findById(Long id) { @Override @CacheEvict(cacheNames = com.divary.global.config.CacheConfig.CACHE_MEMBER_BY_ID, key = "#member.id", condition = "#member.id != null") public Member saveMember(Member member) { + // If member has an ID, it might be a detached entity from cache + // Re-fetch from DB to get managed entity with proper version + if (member.getId() != null) { + Member managedMember = memberRepository.findById(member.getId()) + .orElseThrow(() -> new BusinessException(ErrorCode.MEMBER_NOT_FOUND)); + + // Copy all fields from detached member to managed member + managedMember.setEmail(member.getEmail()); + managedMember.setLevel(member.getLevel()); + managedMember.setRole(member.getRole()); + managedMember.setStatus(member.getStatus()); + managedMember.setDeactivatedAt(member.getDeactivatedAt()); + + return managedMember; // JPA dirty checking will save this + } + + // New entity - just save directly return memberRepository.save(member); } - @CacheEvict(cacheNames = com.divary.global.config.CacheConfig.CACHE_MEMBER_BY_ID, key = "#userId") + @CacheEvict(cacheNames = com.divary.global.config.CacheConfig.CACHE_MEMBER_BY_ID, key = "#userId", beforeInvocation = false) public void updateLevel(Long userId, MyPageLevelRequestDTO requestDTO) { Levels level = EnumValidator.validateEnum(Levels.class, requestDTO.getLevel().name()); - Member member = memberRepository.findById(userId).orElseThrow(()-> new BusinessException(ErrorCode.MEMBER_NOT_FOUND)); member.setLevel(level); + // Cache evicted after successful update } @Override @@ -83,7 +101,7 @@ public MyPageImageResponseDTO uploadLicense(MultipartFile image, Long userId) { @Override @Transactional - @CacheEvict(cacheNames = com.divary.global.config.CacheConfig.CACHE_MEMBER_BY_ID, key = "#memberId") + @CacheEvict(cacheNames = com.divary.global.config.CacheConfig.CACHE_MEMBER_BY_ID, key = "#memberId", beforeInvocation = false) public DeactivateResponse requestToDeleteMember(Long memberId) { Member member = memberRepository.findById(memberId).orElseThrow(()-> new BusinessException(ErrorCode.MEMBER_NOT_FOUND)); @@ -96,11 +114,12 @@ public DeactivateResponse requestToDeleteMember(Long memberId) { .plusDays(gracePeriodDays); return new DeactivateResponse(scheduledDeletionAt); + // Cache evicted after successful update } @Override @Transactional - @CacheEvict(cacheNames = com.divary.global.config.CacheConfig.CACHE_MEMBER_BY_ID, key = "#memberId") + @CacheEvict(cacheNames = com.divary.global.config.CacheConfig.CACHE_MEMBER_BY_ID, key = "#memberId", beforeInvocation = false) public void cancelDeleteMember(Long memberId) { Member member = memberRepository.findById(memberId).orElseThrow(() -> new BusinessException(ErrorCode.MEMBER_NOT_FOUND)); @@ -108,6 +127,7 @@ public void cancelDeleteMember(Long memberId) { if (member.getStatus() == Status.DEACTIVATED) { member.cancelDeletion(); } + // Cache evicted after successful update } @Override @Transactional