Skip to content

Commit

Permalink
refactor: Member엔티티와 StudyMember엔티티의 연관관계 관련 코드 수정
Browse files Browse the repository at this point in the history
  • Loading branch information
donghyun0304 committed Jul 2, 2024
1 parent 0341f0a commit 7c02925
Show file tree
Hide file tree
Showing 6 changed files with 52 additions and 53 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

import static com.example.demo.exception.ExceptionType.*;

import java.time.LocalDate;
import java.time.LocalDateTime;

import org.springframework.http.HttpStatus;
Expand Down Expand Up @@ -85,8 +84,7 @@ public ResponseEntity<StudyOnceCreateResponse> create(
@RequestBody @Validated StudyOnceCreateRequest studyOnceCreateRequest,
@RequestHeader("Authorization") String authorization) {
long memberId = cafegoryTokenManager.getIdentityId(authorization);
StudyOnceCreateResponse response = studyOnceService.createStudy(memberId, studyOnceCreateRequest,
LocalDate.now());
StudyOnceCreateResponse response = studyOnceService.createStudy(memberId, studyOnceCreateRequest);
return ResponseEntity.ok(response);
}

Expand Down
17 changes: 10 additions & 7 deletions src/main/java/com/example/demo/domain/member/Member.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import static com.example.demo.exception.ExceptionType.*;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

Expand All @@ -14,9 +15,9 @@
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import javax.persistence.Table;
import javax.persistence.Transient;

import com.example.demo.domain.study.StudyMember;
import com.example.demo.exception.CafegoryException;
Expand All @@ -26,7 +27,6 @@
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

@Entity
@Builder
Expand All @@ -48,15 +48,13 @@ public class Member {
@OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.PERSIST)
@JoinColumn(name = "thumbnail_image_id", foreignKey = @ForeignKey(ConstraintMode.NO_CONSTRAINT))
private ThumbnailImage thumbnailImage;
@Transient

@Builder.Default
// 회원은 오래 활동한 경우 매우 많은 스터디에 참여했을 수 있다. 따라서 이를 무작정 모두 조회하면 메모리 오버플로우가 발생할 수 있다.
// 별도의 레퍼지토리를 통해 적절한 범위의 StudyMember 엔티티를 조회한 뒤 주입해야 한다.
@Setter
@OneToMany(mappedBy = "member")
private List<StudyMember> studyMembers = new ArrayList<>();

public void addStudyMember(StudyMember studyMember) {
studyMembers.add(studyMember);
this.studyMembers.add(studyMember);
}

public void updateProfile(String name, String introduction) {
Expand All @@ -71,4 +69,9 @@ private void validateIntroduction(String introduction) {
}
}

public boolean hasStudyScheduleConflict(LocalDateTime start, LocalDateTime end) {
return this.studyMembers.stream()
.anyMatch(studyMember -> studyMember.isConflictWith(start, end));
}

}
28 changes: 14 additions & 14 deletions src/main/java/com/example/demo/domain/study/StudyOnce.java
Original file line number Diff line number Diff line change
Expand Up @@ -87,9 +87,11 @@ private StudyOnce(Long id, String name, Cafe cafe, LocalDateTime startDateTime,
validateEmptyOrWhiteSpace(openChatUrl, STUDY_ONCE_OPEN_CHAT_URL_EMPTY_OR_WHITESPACE);
this.openChatUrl = openChatUrl;
this.leader = leader;
validateConflictJoin(leader);
validateStudyScheduleConflict(leader);
studyMembers = new ArrayList<>();
studyMembers.add(new StudyMember(leader, this));
StudyMember studyMember = new StudyMember(leader, this);
studyMembers.add(studyMember);
leader.addStudyMember(studyMember);
this.nowMemberCount = 1;
}

Expand Down Expand Up @@ -131,15 +133,15 @@ private void validateNowMemberCountOverMaxLimit(int nowMemberCount, int maxMembe
}
}

public void tryJoin(Member memberThatExpectedToJoin, LocalDateTime requestTime) {
public void tryJoin(Member member, LocalDateTime requestTime) {
validateJoinRequestTime(requestTime);
validateDuplicateJoin(memberThatExpectedToJoin);
validateConflictJoin(memberThatExpectedToJoin);
validateDuplicateJoin(member);
validateStudyScheduleConflict(member);
validateStudyMemberIsFull();
StudyMember studyMember = new StudyMember(memberThatExpectedToJoin, this);
studyMembers.add(studyMember);
memberThatExpectedToJoin.addStudyMember(studyMember);
nowMemberCount = studyMembers.size();
StudyMember studyMember = new StudyMember(member, this);
this.studyMembers.add(studyMember);
member.addStudyMember(studyMember);
this.nowMemberCount = this.studyMembers.size();
}

private void validateStudyMemberIsFull() {
Expand All @@ -148,11 +150,9 @@ private void validateStudyMemberIsFull() {
}
}

private void validateConflictJoin(Member memberThatExpectedToJoin) {
boolean joinFail = memberThatExpectedToJoin.getStudyMembers()
.stream()
.anyMatch(studyMember -> studyMember.isConflictWith(startDateTime, endDateTime));
if (joinFail) {
private void validateStudyScheduleConflict(Member member) {
boolean isStudyConflict = member.hasStudyScheduleConflict(this.startDateTime, this.endDateTime);
if (isStudyConflict) {
throw new CafegoryException(STUDY_ONCE_CONFLICT_TIME);
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package com.example.demo.service.study;

import java.time.LocalDate;
import java.time.LocalDateTime;

import com.example.demo.domain.study.Attendance;
Expand Down Expand Up @@ -32,8 +31,7 @@ UpdateAttendanceResponse updateAttendances(long leaderId, long studyOnceId,

void updateAttendance(long leaderId, long studyOnceId, long memberId, Attendance attendance, LocalDateTime now);

StudyOnceCreateResponse createStudy(long leaderId, StudyOnceCreateRequest studyOnceCreateRequest,
LocalDate nowDate);
StudyOnceCreateResponse createStudy(long leaderId, StudyOnceCreateRequest studyOnceCreateRequest);

Long changeCafe(Long requestMemberId, Long studyOnceId, Long changingCafeId);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import static com.example.demo.exception.ExceptionType.*;

import java.time.Duration;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.List;
Expand Down Expand Up @@ -58,11 +57,10 @@ public class StudyOnceServiceImpl implements StudyOnceService {
private final BusinessHourOpenChecker openChecker = new BusinessHourOpenChecker();

@Override
public void tryJoin(long memberIdThatExpectedToJoin, long studyId) {
public void tryJoin(long memberId, long studyId) {
StudyOnce studyOnce = studyOnceRepository.findById(studyId)
.orElseThrow(() -> new CafegoryException(STUDY_ONCE_NOT_FOUND));
LocalDateTime startDateTime = studyOnce.getStartDateTime();
Member member = getMember(memberIdThatExpectedToJoin, startDateTime);
Member member = findMemberById(memberId);
studyOnce.tryJoin(member, LocalDateTime.now());
}

Expand Down Expand Up @@ -195,17 +193,25 @@ private StudyOnce findStudyOnceById(long studyOnceId) {
}

@Override
public StudyOnceCreateResponse createStudy(long leaderId, StudyOnceCreateRequest request, LocalDate nowDate) {
public StudyOnceCreateResponse createStudy(long leaderId, StudyOnceCreateRequest request) {
Cafe cafe = findCafeById(request.getCafeId());
BusinessHour businessHour = cafe.findBusinessHour(nowDate.getDayOfWeek());
BusinessHour businessHour = cafe.findBusinessHour(request.getStartDateTime().getDayOfWeek());
validateBetweenBusinessHour(request.getStartDateTime().toLocalTime(), request.getEndDateTime().toLocalTime(),
businessHour);
Member leader = getMember(leaderId, request.getStartDateTime());
Member leader = findMemberById(leaderId);
validateStudyScheduleConflict(request.getStartDateTime(), request.getEndDateTime(), leader);
StudyOnce studyOnce = studyOnceMapper.toNewEntity(request, cafe, leader);
StudyOnce saved = studyOnceRepository.save(studyOnce);
return studyOnceMapper.toStudyOnceCreateResponse(saved, true);
}

private void validateStudyScheduleConflict(LocalDateTime start, LocalDateTime end, Member leader) {
boolean isScheduleConflict = leader.hasStudyScheduleConflict(start, end);
if (isScheduleConflict) {
throw new CafegoryException(STUDY_ONCE_CONFLICT_TIME);
}
}

private void validateBetweenBusinessHour(LocalTime studyOnceStartTime, LocalTime studyOnceEndTime,
BusinessHour businessHour) {
boolean isBetweenBusinessHour = openChecker.checkBetweenBusinessHours(businessHour.getStartTime(),
Expand Down Expand Up @@ -303,7 +309,7 @@ private Member getMember(long leaderId, LocalDateTime startDateTime) {
Member leader = memberRepository.findById(leaderId)
.orElseThrow(() -> new CafegoryException(MEMBER_NOT_FOUND));
var studyMembers = studyMemberRepository.findByMemberAndStudyDate(leader, startDateTime.toLocalDate());
leader.setStudyMembers(studyMembers);
// leader.setStudyMembers(studyMembers);
return leader;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
import static org.assertj.core.api.Assertions.*;
import static org.junit.jupiter.api.Assertions.*;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.ArrayList;
Expand All @@ -15,8 +14,6 @@
import java.util.stream.Collectors;
import java.util.stream.Stream;

import javax.transaction.Transactional;

import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
Expand All @@ -26,6 +23,7 @@
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.annotation.Import;
import org.springframework.transaction.annotation.Transactional;

import com.example.demo.config.TestConfig;
import com.example.demo.domain.cafe.BusinessHour;
Expand Down Expand Up @@ -57,7 +55,6 @@
class StudyOnceServiceImplTest {

private static final LocalDateTime NOW = LocalDateTime.now();

@Autowired
private StudyOnceService sut;
@Autowired
Expand Down Expand Up @@ -102,8 +99,7 @@ void searchByStudyId_when_not_member() {
ThumbnailImage thumbnailImage = thumbnailImageSaveHelper.saveThumbnailImage();
long leaderId = memberSaveHelper.saveMember(thumbnailImage).getId();
StudyOnceCreateRequest studyOnceCreateRequest = makeStudyOnceCreateRequest(start, end, cafeId);
StudyOnceCreateResponse result = sut.createStudy(leaderId, studyOnceCreateRequest,
LocalDate.now());
StudyOnceCreateResponse result = sut.createStudy(leaderId, studyOnceCreateRequest);

StudyOnceSearchResponse studyOnceSearchResponse = sut.searchByStudyId(result.getStudyOnceId());

Expand All @@ -120,8 +116,7 @@ void searchStudyOnceWithMemberParticipation_when_takes_attendance() {
StudyOnceCreateRequest studyOnceCreateRequest = makeStudyOnceCreateRequest(start, end, cafeId);
ThumbnailImage thumbnailImage = thumbnailImageSaveHelper.saveThumbnailImage();
long leaderId = memberSaveHelper.saveMember(thumbnailImage).getId();
StudyOnceCreateResponse searchResponse = sut.createStudy(leaderId, studyOnceCreateRequest,
LocalDate.now());
StudyOnceCreateResponse searchResponse = sut.createStudy(leaderId, studyOnceCreateRequest);
long studyOnceId = searchResponse.getStudyOnceId();
long memberId = memberSaveHelper.saveMember(thumbnailImage).getId();
sut.tryJoin(memberId, studyOnceId);
Expand All @@ -143,8 +138,7 @@ void searchStudyOnceWithMemberParticipation_when_not_take_attendance() {
StudyOnceCreateRequest studyOnceCreateRequest = makeStudyOnceCreateRequest(start, end, cafeId);
ThumbnailImage thumbnailImage = thumbnailImageSaveHelper.saveThumbnailImage();
long leaderId = memberSaveHelper.saveMember(thumbnailImage).getId();
StudyOnceCreateResponse searchResponse = sut.createStudy(leaderId, studyOnceCreateRequest,
LocalDate.now());
StudyOnceCreateResponse searchResponse = sut.createStudy(leaderId, studyOnceCreateRequest);
long studyOnceId = searchResponse.getStudyOnceId();
long memberId = memberSaveHelper.saveMember(thumbnailImage).getId();

Expand All @@ -165,7 +159,7 @@ void exception_case1() {
Cafe cafe = cafeSaveHelper.saveCafeWith24For7();
StudyOnceCreateRequest studyOnceCreateRequest = makeStudyOnceCreateRequest(start, end, cafe.getId());
//then
assertDoesNotThrow(() -> sut.createStudy(leader.getId(), studyOnceCreateRequest, LocalDate.now()));
assertDoesNotThrow(() -> sut.createStudy(leader.getId(), studyOnceCreateRequest));
}

@Test
Expand All @@ -180,7 +174,7 @@ void study_starts_3hours_after_now() {
Cafe cafe = cafeSaveHelper.saveCafeWith24For7();
StudyOnceCreateRequest studyOnceCreateRequest = makeStudyOnceCreateRequest(start, end, cafe.getId());
//then
assertDoesNotThrow(() -> sut.createStudy(leader.getId(), studyOnceCreateRequest, LocalDate.now()));
assertDoesNotThrow(() -> sut.createStudy(leader.getId(), studyOnceCreateRequest));
}

@Test
Expand All @@ -194,7 +188,7 @@ void study_duration_must_be_at_least_1hour() {
Cafe cafe = cafeSaveHelper.saveCafeWith24For7();
StudyOnceCreateRequest request = makeStudyOnceCreateRequest(start, end, cafe.getId());
//then
assertThatThrownBy(() -> sut.createStudy(leader.getId(), request, LocalDate.now()))
assertThatThrownBy(() -> sut.createStudy(leader.getId(), request))
.isInstanceOf(CafegoryException.class)
.hasMessage(STUDY_ONCE_SHORT_DURATION.getErrorMessage());
}
Expand All @@ -211,7 +205,7 @@ void study_duration_can_not_exceed_5hours() {
Cafe cafe = cafeSaveHelper.saveCafeWith24For7();
StudyOnceCreateRequest request = makeStudyOnceCreateRequest(start, end, cafe.getId());
//then
assertThatThrownBy(() -> sut.createStudy(leader.getId(), request, LocalDate.now()))
assertThatThrownBy(() -> sut.createStudy(leader.getId(), request))
.isInstanceOf(CafegoryException.class)
.hasMessage(STUDY_ONCE_LONG_DURATION.getErrorMessage());
}
Expand All @@ -228,7 +222,7 @@ void check_study_duration_limits(int duration) {
Cafe cafe = cafeSaveHelper.saveCafeWith24For7();
StudyOnceCreateRequest studyOnceCreateRequest = makeStudyOnceCreateRequest(start, end, cafe.getId());
//then
assertDoesNotThrow(() -> sut.createStudy(leader.getId(), studyOnceCreateRequest, LocalDate.now()));
assertDoesNotThrow(() -> sut.createStudy(leader.getId(), studyOnceCreateRequest));
}

@ParameterizedTest
Expand All @@ -249,7 +243,7 @@ void can_not_schedule_several_study_at_the_same_time(LocalDateTime testStartTime
cafe2.getId());
//then
assertThatThrownBy(
() -> sut.createStudy(leader.getId(), request, LocalDate.now()))
() -> sut.createStudy(leader.getId(), request))
.isInstanceOf(CafegoryException.class)
.hasMessage(STUDY_ONCE_CONFLICT_TIME.getErrorMessage());
}
Expand Down Expand Up @@ -309,7 +303,7 @@ void study_can_not_start_outside_cafe_business_hours(LocalDateTime start, LocalD
Member leader = memberSaveHelper.saveMember(thumbnailImage);
StudyOnceCreateRequest studyOnceCreateRequest = makeStudyOnceCreateRequest(start, end, cafe.getId());
//then
assertThatThrownBy(() -> sut.createStudy(leader.getId(), studyOnceCreateRequest, LocalDate.now()))
assertThatThrownBy(() -> sut.createStudy(leader.getId(), studyOnceCreateRequest))
.isInstanceOf(CafegoryException.class)
.hasMessage(STUDY_ONCE_CREATE_BETWEEN_CAFE_BUSINESS_HOURS.getErrorMessage());
}
Expand Down Expand Up @@ -346,7 +340,7 @@ void study_can_start_between_cafe_business_hours(LocalDateTime start, LocalDateT
Member leader = memberSaveHelper.saveMember(thumbnailImage);
StudyOnceCreateRequest studyOnceCreateRequest = makeStudyOnceCreateRequest(start, end, cafe.getId());
//then
assertDoesNotThrow(() -> sut.createStudy(leader.getId(), studyOnceCreateRequest, LocalDate.now()));
assertDoesNotThrow(() -> sut.createStudy(leader.getId(), studyOnceCreateRequest));
}

static Stream<Arguments> provideStartAndEndDateTime2() {
Expand Down

0 comments on commit 7c02925

Please sign in to comment.