diff --git a/backend/src/main/java/com/woowacourse/friendogly/club/domain/ClubMember.java b/backend/src/main/java/com/woowacourse/friendogly/club/domain/ClubMember.java index 44ccc88c2..7d6e3d69b 100644 --- a/backend/src/main/java/com/woowacourse/friendogly/club/domain/ClubMember.java +++ b/backend/src/main/java/com/woowacourse/friendogly/club/domain/ClubMember.java @@ -2,7 +2,6 @@ import com.woowacourse.friendogly.exception.FriendoglyException; import com.woowacourse.friendogly.member.domain.Member; -import jakarta.persistence.CascadeType; import jakarta.persistence.Entity; import jakarta.persistence.FetchType; import jakarta.persistence.GeneratedValue; @@ -10,9 +9,6 @@ import jakarta.persistence.Id; import jakarta.persistence.JoinColumn; import jakarta.persistence.ManyToOne; -import jakarta.persistence.OneToMany; -import java.util.ArrayList; -import java.util.List; import lombok.AccessLevel; import lombok.Builder; import lombok.Getter; @@ -35,9 +31,6 @@ public class ClubMember { @JoinColumn(name = "member_id", nullable = false) private Member member; - @OneToMany(mappedBy = "clubMember", orphanRemoval = true, cascade = CascadeType.ALL) - private List clubMemberPets = new ArrayList<>(); - @Builder public ClubMember(Club club, Member member) { validateClub(club); @@ -57,17 +50,4 @@ private void validateMember(Member member) { throw new FriendoglyException("모임에 참여하는 회원 정보는 필수입니다."); } } - - public void addClubMemberPets(ClubMemberPet pet) { - //TODO : 데려갈 수 있는 최대 반려견이 정해지면 예외처리 - //TODO : 해당 팻이 member가 키우는 팻인지 검증 - clubMemberPets.add(pet); - } - - public String findOverviewPetImage() { - if (clubMemberPets.isEmpty()) { - return null; - } - return clubMemberPets.get(0).getPet().getImageUrl().getValue(); - } } diff --git a/backend/src/main/java/com/woowacourse/friendogly/club/domain/ClubMemberPet.java b/backend/src/main/java/com/woowacourse/friendogly/club/domain/ClubPet.java similarity index 78% rename from backend/src/main/java/com/woowacourse/friendogly/club/domain/ClubMemberPet.java rename to backend/src/main/java/com/woowacourse/friendogly/club/domain/ClubPet.java index 3d4e3fcd2..741ff7066 100644 --- a/backend/src/main/java/com/woowacourse/friendogly/club/domain/ClubMemberPet.java +++ b/backend/src/main/java/com/woowacourse/friendogly/club/domain/ClubPet.java @@ -17,30 +17,30 @@ @Entity @NoArgsConstructor(access = AccessLevel.PROTECTED) @Getter -public class ClubMemberPet { +public class ClubPet { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @ManyToOne(optional = false, fetch = FetchType.LAZY) - @JoinColumn(name = "club_member_id", nullable = false) - private ClubMember clubMember; + @JoinColumn(name = "club_id", nullable = false) + private Club club; @ManyToOne(optional = false, fetch = FetchType.LAZY) @JoinColumn(name = "pet_id", nullable = false) private Pet pet; @Builder - public ClubMemberPet(ClubMember clubMember, Pet pet) { - validateClubMember(clubMember); + public ClubPet(Club club, Pet pet) { + validateClub(club); validatePet(pet); - this.clubMember = clubMember; + this.club = club; this.pet = pet; } - private void validateClubMember(ClubMember clubMember) { - if (clubMember == null) { + private void validateClub(Club club) { + if (club == null) { throw new FriendoglyException("모임에 참여하는 회원 정보는 필수입니다."); } } diff --git a/backend/src/main/java/com/woowacourse/friendogly/club/repository/ClubMemberPetRepository.java b/backend/src/main/java/com/woowacourse/friendogly/club/repository/ClubMemberPetRepository.java deleted file mode 100644 index 19ac0579d..000000000 --- a/backend/src/main/java/com/woowacourse/friendogly/club/repository/ClubMemberPetRepository.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.woowacourse.friendogly.club.repository; - -import com.woowacourse.friendogly.club.domain.ClubMemberPet; -import org.springframework.data.jpa.repository.JpaRepository; - -public interface ClubMemberPetRepository extends JpaRepository { - -} diff --git a/backend/src/main/java/com/woowacourse/friendogly/club/repository/ClubPetRepository.java b/backend/src/main/java/com/woowacourse/friendogly/club/repository/ClubPetRepository.java new file mode 100644 index 000000000..7d299911b --- /dev/null +++ b/backend/src/main/java/com/woowacourse/friendogly/club/repository/ClubPetRepository.java @@ -0,0 +1,12 @@ +package com.woowacourse.friendogly.club.repository; + +import com.woowacourse.friendogly.club.domain.ClubPet; +import java.util.List; +import org.springframework.data.jpa.repository.EntityGraph; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface ClubPetRepository extends JpaRepository { + + @EntityGraph(attributePaths = {"club", "pet"}) + List findAllByClubId(Long id); +} diff --git a/backend/src/main/java/com/woowacourse/friendogly/club/service/ClubQueryService.java b/backend/src/main/java/com/woowacourse/friendogly/club/service/ClubQueryService.java index 3701b1170..dcefafc32 100644 --- a/backend/src/main/java/com/woowacourse/friendogly/club/service/ClubQueryService.java +++ b/backend/src/main/java/com/woowacourse/friendogly/club/service/ClubQueryService.java @@ -1,14 +1,19 @@ package com.woowacourse.friendogly.club.service; +import static java.util.stream.Collectors.toList; + import com.woowacourse.friendogly.club.domain.Club; -import com.woowacourse.friendogly.club.domain.ClubMember; +import com.woowacourse.friendogly.club.domain.ClubPet; import com.woowacourse.friendogly.club.dto.request.FindSearchingClubRequest; import com.woowacourse.friendogly.club.dto.response.FindSearchingClubResponse; -import com.woowacourse.friendogly.club.repository.ClubMemberPetRepository; import com.woowacourse.friendogly.club.repository.ClubMemberRepository; +import com.woowacourse.friendogly.club.repository.ClubPetRepository; import com.woowacourse.friendogly.club.repository.ClubRepository; import com.woowacourse.friendogly.club.repository.ClubSpecification; +import com.woowacourse.friendogly.pet.domain.Pet; import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; import org.springframework.data.jpa.domain.Specification; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -19,16 +24,16 @@ public class ClubQueryService { private final ClubRepository clubRepository; private final ClubMemberRepository clubMemberRepository; - private final ClubMemberPetRepository clubMemberPetRepository; + private final ClubPetRepository clubPetRepository; public ClubQueryService( ClubRepository clubRepository, ClubMemberRepository clubMemberRepository, - ClubMemberPetRepository clubMemberPetRepository + ClubPetRepository clubPetRepository ) { this.clubRepository = clubRepository; this.clubMemberRepository = clubMemberRepository; - this.clubMemberPetRepository = clubMemberPetRepository; + this.clubPetRepository = clubPetRepository; } public List findSearching(FindSearchingClubRequest request) { @@ -39,18 +44,23 @@ public List findSearching(FindSearchingClubRequest re .build(); return clubRepository.findAll(spec).stream() - .map(club -> { - List overviewPetImages = clubMemberRepository.findAllByClubId(club.getId()).stream() - .map(ClubMember::findOverviewPetImage) - .toList(); - return new FindSearchingClubResponse( - club, - clubMemberRepository.countByClubId(club.getId()), - overviewPetImages - ); - }) + .map(club -> new FindSearchingClubResponse( + club, + clubMemberRepository.countByClubId(club.getId()), + collectOverviewPetImages(club) + )) .toList(); } + + private List collectOverviewPetImages(Club club) { + Map> groupPetsByMemberId = clubPetRepository.findAllByClubId(club.getId()).stream() + .map(ClubPet::getPet) + .collect(Collectors.groupingBy(pet -> pet.getMember().getId())); + + return groupPetsByMemberId.values().stream() + .map(petList -> petList.get(0).getImageUrl().getValue()) + .collect(toList()); + } } diff --git a/backend/src/test/java/com/woowacourse/friendogly/club/domain/ClubMemberTest.java b/backend/src/test/java/com/woowacourse/friendogly/club/domain/ClubMemberTest.java index 92756fbf2..9e5e4b815 100644 --- a/backend/src/test/java/com/woowacourse/friendogly/club/domain/ClubMemberTest.java +++ b/backend/src/test/java/com/woowacourse/friendogly/club/domain/ClubMemberTest.java @@ -1,6 +1,5 @@ package com.woowacourse.friendogly.club.domain; -import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatCode; import static org.assertj.core.api.Assertions.assertThatThrownBy; @@ -74,31 +73,4 @@ void create_FailNullMember() { .isInstanceOf(FriendoglyException.class) .hasMessage("모임에 참여하는 회원 정보는 필수입니다."); } - - @DisplayName("리스트업에 나오는 참여 강아지 사진을 반환한다.") - @Test - void findClubOverviewPetImage() { - ClubMember clubMember = ClubMember.builder() - .club(club) - .member(member) - .build(); - - clubMember.addClubMemberPets(ClubMemberPet.builder() - .clubMember(clubMember) - .pet(pet) - .build()); - - assertThat(clubMember.findOverviewPetImage()).isEqualTo(pet.getImageUrl().getValue()); - } - - @DisplayName("참여 중인 회원이 어떤 강아지도 데리고 가지 않는다면 null을 반환한다.") - @Test - void findClubOverviewPetImage_FailNonPets() { - ClubMember clubMember = ClubMember.builder() - .club(club) - .member(member) - .build(); - - assertThat(clubMember.findOverviewPetImage()).isNull(); - } } diff --git a/backend/src/test/java/com/woowacourse/friendogly/club/service/ClubQueryServiceTest.java b/backend/src/test/java/com/woowacourse/friendogly/club/service/ClubQueryServiceTest.java index c4cc671c2..2f45dba1d 100644 --- a/backend/src/test/java/com/woowacourse/friendogly/club/service/ClubQueryServiceTest.java +++ b/backend/src/test/java/com/woowacourse/friendogly/club/service/ClubQueryServiceTest.java @@ -23,8 +23,7 @@ class ClubQueryServiceTest extends ClubServiceTest { @DisplayName("필터링된 모임을 정보를 조회한다.") @Test void findSearching() { - //서울특별시 송파구 신청동, (암컷, 중성화 암컷), 크기는 소형견이 조건인 club - Club club = saveNewClub(); + Club club = getSavedClub(Set.of(Gender.FEMALE, Gender.FEMALE_NEUTERED), Set.of(SizeType.SMALL)); FindSearchingClubRequest request = new FindSearchingClubRequest( address, @@ -54,4 +53,20 @@ void findSearching() { () -> assertThat(actual.petImageUrls()).containsExactlyInAnyOrderElementsOf(expected.petImageUrls()) ); } + + @DisplayName("필터링된 모임을 정보가 없으면 빈 리스트를 반환한다.") + @Test + void findSearching_Nothing() { + Club club = getSavedClub(Set.of(Gender.FEMALE, Gender.FEMALE_NEUTERED), Set.of(SizeType.SMALL)); + + FindSearchingClubRequest request = new FindSearchingClubRequest( + address, + Set.of(Gender.MALE), + Set.of(SizeType.SMALL) + ); + + List responses = clubQueryService.findSearching(request); + + assertThat(responses.isEmpty()).isTrue(); + } } diff --git a/backend/src/test/java/com/woowacourse/friendogly/club/service/ClubServiceTest.java b/backend/src/test/java/com/woowacourse/friendogly/club/service/ClubServiceTest.java index 3089baba3..69763fbd6 100644 --- a/backend/src/test/java/com/woowacourse/friendogly/club/service/ClubServiceTest.java +++ b/backend/src/test/java/com/woowacourse/friendogly/club/service/ClubServiceTest.java @@ -2,7 +2,7 @@ import com.woowacourse.friendogly.club.domain.Club; import com.woowacourse.friendogly.club.domain.ClubMember; -import com.woowacourse.friendogly.club.domain.ClubMemberPet; +import com.woowacourse.friendogly.club.domain.ClubPet; import com.woowacourse.friendogly.member.domain.Member; import com.woowacourse.friendogly.pet.domain.Gender; import com.woowacourse.friendogly.pet.domain.Pet; @@ -33,31 +33,32 @@ public abstract class ClubServiceTest extends ServiceTest { .sizeType(SizeType.SMALL) .build(); - private final Club club = Club.create( - "강아지 산책시키실 분 모아요.", - "매주 주말에 정기적으로 산책 모임하실분만", - address, - 5, - member, - allowedGenders, - allowedSizes, - "https://image.com"); - - protected Club saveNewClub() { + protected Club getSavedClub(Set genders, Set sizes) { memberRepository.save(member); petRepository.save(pet); + + Club club = Club.create( + "강아지 산책시키실 분 모아요.", + "매주 주말에 정기적으로 산책 모임하실분만", + address, + 5, + member, + genders, + sizes, + "https://image.com"); + Club savedClub = clubRepository.save(club); ClubMember clubMember = ClubMember.builder() .member(member) .club(club) .build(); - ClubMemberPet clubMemberPet = ClubMemberPet.builder() - .clubMember(clubMember) + ClubPet clubPet = ClubPet.builder() + .club(club) .pet(pet) .build(); clubMemberRepository.save(clubMember); - clubMemberPetRepository.save(clubMemberPet); + clubPetRepository.save(clubPet); return savedClub; } diff --git a/backend/src/test/java/com/woowacourse/friendogly/support/ServiceTest.java b/backend/src/test/java/com/woowacourse/friendogly/support/ServiceTest.java index 22c7c242a..ddc5fba54 100644 --- a/backend/src/test/java/com/woowacourse/friendogly/support/ServiceTest.java +++ b/backend/src/test/java/com/woowacourse/friendogly/support/ServiceTest.java @@ -1,7 +1,7 @@ package com.woowacourse.friendogly.support; -import com.woowacourse.friendogly.club.repository.ClubMemberPetRepository; import com.woowacourse.friendogly.club.repository.ClubMemberRepository; +import com.woowacourse.friendogly.club.repository.ClubPetRepository; import com.woowacourse.friendogly.club.repository.ClubRepository; import com.woowacourse.friendogly.footprint.repository.FootprintRepository; import com.woowacourse.friendogly.member.repository.MemberRepository; @@ -20,7 +20,7 @@ public abstract class ServiceTest { protected ClubMemberRepository clubMemberRepository; @Autowired - protected ClubMemberPetRepository clubMemberPetRepository; + protected ClubPetRepository clubPetRepository; @Autowired protected MemberRepository memberRepository; @@ -34,7 +34,7 @@ public abstract class ServiceTest { @BeforeEach void clearDB() { clubMemberRepository.deleteAll(); - clubMemberPetRepository.deleteAll(); + clubPetRepository.deleteAll(); clubRepository.deleteAll(); footprintRepository.deleteAll(); petRepository.deleteAll();