Skip to content

Commit

Permalink
Merge branch 'develop' into feature/#538-member-profile-image-change
Browse files Browse the repository at this point in the history
  • Loading branch information
s6m1n committed Feb 6, 2025
2 parents c888c0b + 7f58bc0 commit 4cf2d6f
Show file tree
Hide file tree
Showing 15 changed files with 140 additions and 55 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,5 @@ public interface CommentRepository extends JpaRepository<Comment, Long> {

@Modifying
@Query("DELETE FROM Comment c WHERE c.moment.id IN :momentIds")
void deleteAllByMomentIdInBatch(@Param("momentIds") List<Long> momentIds);
void deleteAllByMomentIdInBulk(@Param("momentIds") List<Long> momentIds);
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,5 +25,5 @@ public interface MemoryMemberRepository extends JpaRepository<MemoryMember, Long

@Modifying
@Query("DELETE FROM MemoryMember mm WHERE mm.memory.id = :memoryId")
void deleteAllByMemoryIdInBatch(@Param("memoryId") Long memoryId);
void deleteAllByMemoryIdInBulk(@Param("memoryId") Long memoryId);
}
Original file line number Diff line number Diff line change
Expand Up @@ -137,9 +137,9 @@ private void deleteAllRelatedMemory(long memoryId) {
.stream()
.map(Moment::getId)
.toList();
momentImageRepository.deleteAllByMomentIdInBatch(momentIds);
commentRepository.deleteAllByMomentIdInBatch(momentIds);
momentRepository.deleteAllByMemoryIdInBatch(memoryId);
memoryMemberRepository.deleteAllByMemoryIdInBatch(memoryId);
momentImageRepository.deleteAllByMomentIdInBulk(momentIds);
commentRepository.deleteAllByMomentIdInBulk(momentIds);
momentRepository.deleteAllByMemoryIdInBulk(memoryId);
memoryMemberRepository.deleteAllByMemoryIdInBulk(memoryId);
}
}
17 changes: 6 additions & 11 deletions backend/src/main/java/com/staccato/moment/domain/Moment.java
Original file line number Diff line number Diff line change
Expand Up @@ -74,17 +74,12 @@ private void validateIsWithinMemoryDuration(LocalDateTime visitedAt, Memory memo
}
}

public void update(String title, MomentImages newMomentImages) {
this.title = title;
this.momentImages.update(newMomentImages, this);
}

public void update(Moment updatedMoment) {
this.visitedAt = updatedMoment.getVisitedAt();
this.title = updatedMoment.getTitle();
this.spot = updatedMoment.getSpot();
this.momentImages.update(updatedMoment.momentImages, this);
this.memory = updatedMoment.getMemory();
public void update(Moment newMoment) {
this.visitedAt = newMoment.getVisitedAt();
this.title = newMoment.getTitle();
this.spot = newMoment.getSpot();
this.momentImages.update(newMoment.momentImages, this);
this.memory = newMoment.getMemory();
}

public String getThumbnailUrl() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;

import lombok.AccessLevel;
import lombok.Builder;
import lombok.Getter;
Expand All @@ -36,4 +35,8 @@ public MomentImage(@Nonnull String imageUrl) {
protected void belongTo(Moment moment) {
this.moment = moment;
}

protected boolean isSame(MomentImage momentImage) {
return imageUrl.equals(momentImage.imageUrl);
}
}
36 changes: 28 additions & 8 deletions backend/src/main/java/com/staccato/moment/domain/MomentImages.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class MomentImages {
private static final int MAX_COUNT = 5;
@OneToMany(mappedBy = "moment", cascade = CascadeType.ALL, orphanRemoval = true)
@OneToMany(mappedBy = "moment", cascade = CascadeType.PERSIST)
private List<MomentImage> images = new ArrayList<>();

public MomentImages(List<String> addedImages) {
Expand All @@ -38,16 +38,36 @@ protected void addAll(MomentImages newMomentImages, Moment moment) {
});
}

protected void update(MomentImages momentImages, Moment moment) {
removeExistsImages(new ArrayList<>(images));
addAll(momentImages, moment);
public boolean isNotEmpty() {
return !images.isEmpty();
}

private void removeExistsImages(List<MomentImage> originalImages) {
originalImages.forEach(this.images::remove);
public List<MomentImage> findImagesNotPresentIn(MomentImages targetMomentImages) {
return images.stream()
.filter(image -> !targetMomentImages.contains(image))
.toList();
}

public boolean isNotEmpty() {
return !images.isEmpty();
protected void update(MomentImages newMomentImages, Moment moment) {
removeExistImages(newMomentImages);
saveNewImages(newMomentImages, moment);
}

private void removeExistImages(MomentImages newMomentImages) {
List<MomentImage> momentImages = findImagesNotPresentIn(newMomentImages);
images.removeAll(momentImages);
}

private void saveNewImages(MomentImages newMomentImages, Moment moment) {
List<MomentImage> momentImages = newMomentImages.findImagesNotPresentIn(this);
momentImages.forEach(image -> {
this.images.add(image);
image.belongTo(moment);
});
}

private boolean contains(MomentImage momentImage) {
return this.images.stream()
.anyMatch(image -> image.isSame(momentImage));
}
}
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
package com.staccato.moment.repository;

import java.util.List;
import java.util.Optional;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import com.staccato.moment.domain.MomentImage;

public interface MomentImageRepository extends JpaRepository<MomentImage, Long> {
Optional<MomentImage> findFirstByMomentId(long momentId);

@Modifying
@Query("DELETE FROM MomentImage mi WHERE mi.moment.id In :momentIds")
void deleteAllByMomentIdInBatch(@Param("momentIds") List<Long> momentIds);
void deleteAllByMomentIdInBulk(@Param("momentIds") List<Long> momentIds);

@Modifying
@Query("DELETE FROM MomentImage mi WHERE mi.id In :ids")
void deleteAllByIdInBulk(@Param("ids") List<Long> ids);
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,5 @@ public interface MomentRepository extends JpaRepository<Moment, Long> {

@Modifying
@Query("DELETE FROM Moment m WHERE m.memory.id = :memoryId")
void deleteAllByMemoryIdInBatch(@Param("memoryId") Long memoryId);
void deleteAllByMemoryIdInBulk(@Param("memoryId") Long memoryId);
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
import com.staccato.memory.repository.MemoryRepository;
import com.staccato.moment.domain.Feeling;
import com.staccato.moment.domain.Moment;
import com.staccato.moment.domain.MomentImage;
import com.staccato.moment.domain.MomentImages;
import com.staccato.moment.repository.MomentImageRepository;
import com.staccato.moment.repository.MomentRepository;
import com.staccato.moment.service.dto.request.FeelingRequest;
Expand Down Expand Up @@ -43,11 +45,6 @@ public MomentIdResponse createMoment(MomentRequest momentRequest, Member member)
return new MomentIdResponse(moment.getId());
}

private Memory getMemoryById(long memoryId) {
return memoryRepository.findById(memoryId)
.orElseThrow(() -> new StaccatoException("요청하신 추억을 찾을 수 없어요."));
}

public MomentLocationResponses readAllMoment(Member member) {
return new MomentLocationResponses(momentRepository.findAllByMemory_MemoryMembers_Member(member)
.stream()
Expand All @@ -72,21 +69,32 @@ public void updateMomentById(
Memory targetMemory = getMemoryById(momentRequest.memoryId());
validateMemoryOwner(targetMemory, member);

Moment updatedMoment = momentRequest.toMoment(targetMemory);
moment.update(updatedMoment);
Moment newMoment = momentRequest.toMoment(targetMemory);
MomentImages originMomentImages = moment.getMomentImages();
List<MomentImage> images = originMomentImages.findImagesNotPresentIn(newMoment.getMomentImages());
removeImages(images);

moment.update(newMoment);
}

private Moment getMomentById(long momentId) {
return momentRepository.findById(momentId)
.orElseThrow(() -> new StaccatoException("요청하신 스타카토를 찾을 수 없어요."));
private void removeImages(List<MomentImage> images) {
List<Long> ids = images.stream()
.map(MomentImage::getId)
.toList();
momentImageRepository.deleteAllByIdInBulk(ids);
}

private Memory getMemoryById(long memoryId) {
return memoryRepository.findById(memoryId)
.orElseThrow(() -> new StaccatoException("요청하신 추억을 찾을 수 없어요."));
}

@Transactional
public void deleteMomentById(long momentId, Member member) {
momentRepository.findById(momentId).ifPresent(moment -> {
validateMemoryOwner(moment.getMemory(), member);
commentRepository.deleteAllByMomentIdInBatch(List.of(momentId));
momentImageRepository.deleteAllByMomentIdInBatch(List.of(momentId));
commentRepository.deleteAllByMomentIdInBulk(List.of(momentId));
momentImageRepository.deleteAllByMomentIdInBulk(List.of(momentId));
momentRepository.deleteById(momentId);
});
}
Expand All @@ -99,6 +107,11 @@ public void updateMomentFeelingById(long momentId, Member member, FeelingRequest
moment.changeFeeling(feeling);
}

private Moment getMomentById(long momentId) {
return momentRepository.findById(momentId)
.orElseThrow(() -> new StaccatoException("요청하신 스타카토를 찾을 수 없어요."));
}

private void validateMemoryOwner(Memory memory, Member member) {
if (memory.isNotOwnedBy(member)) {
throw new ForbiddenException();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ class CommentRepositoryTest extends RepositoryTest {

@DisplayName("특정 스타카토의 id를 여러개를 가지고 있는 모든 댓글들을 삭제한다.")
@Test
void deleteAllByMomentIdInBatch() {
void deleteAllByMomentIdInBulk() {
// given
Member member = memberRepository.save(MemberFixture.create());
Memory memory = memoryRepository.save(MemoryFixture.create(null, null));
Expand All @@ -46,7 +46,7 @@ void deleteAllByMomentIdInBatch() {
momentRepository.save(moment2);

// when
commentRepository.deleteAllByMomentIdInBatch(List.of(moment1.getId(), moment2.getId()));
commentRepository.deleteAllByMomentIdInBulk(List.of(moment1.getId(), moment2.getId()));
em.flush();
em.clear();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ void findAllByMemberIdAndDateWhenNull() {

@DisplayName("특정 추억의 id를 가지고 있는 모든 MemoryMember를 삭제한다.")
@Test
void deleteAllByMemoryIdInBatch() {
void deleteAllByMemoryIdInBulk() {
// given
Member member = memberRepository.save(MemberFixture.create());
Member member2 = memberRepository.save(MemberFixture.create("hotea"));
Expand All @@ -90,7 +90,7 @@ void deleteAllByMemoryIdInBatch() {
MemoryMember memoryMember2 = memoryMemberRepository.save(new MemoryMember(member2, memory));

// when
memoryMemberRepository.deleteAllByMemoryIdInBatch(memory.getId());
memoryMemberRepository.deleteAllByMemoryIdInBulk(memory.getId());
entityManager.flush();
entityManager.clear();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,4 +69,25 @@ void update() {
() -> assertThat(images.size()).isEqualTo(2)
);
}

@DisplayName("포함되지 않는 사진들을 선별할 수 있다.")
@Test
void findImagesNotPresentIn() {
// given
MomentImages existingImages = new MomentImages(List.of("picture1", "picture3"));
MomentImages newImages = new MomentImages(List.of("picture1", "picture4"));

// when
List<MomentImage> remainingExistingImages = existingImages.findImagesNotPresentIn(newImages);
List<MomentImage> remainingNewImages = newImages.findImagesNotPresentIn(existingImages);

// then
assertAll(

() -> assertThat(remainingExistingImages.size()).isEqualTo(1),
() -> assertThat(remainingNewImages.size()).isEqualTo(1),
() -> assertThat(remainingExistingImages.get(0).getImageUrl()).isEqualTo("picture3"),
() -> assertThat(remainingNewImages.get(0).getImageUrl()).isEqualTo("picture4")
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import com.staccato.memory.domain.Memory;
import com.staccato.memory.repository.MemoryRepository;
import com.staccato.moment.domain.Moment;
import com.staccato.moment.domain.MomentImage;
import com.staccato.moment.domain.MomentImages;

import static org.assertj.core.api.Assertions.assertThat;
Expand All @@ -29,9 +30,9 @@ class MomentImageRepositoryTest extends RepositoryTest {
@PersistenceContext
private EntityManager em;

@DisplayName("특정 스타카토의 id 여러개를 가지고 있는 모든 스타카토 이미지들을 삭제한다.")
@DisplayName("특정 스타카토의 id 여러개를 가지고 있는 모든 스타카토 이미지들을 벌크 삭제한다.")
@Test
void deleteAllByMomentIdInBatch() {
void deleteAllByMomentIdInBulk() {
// given
Memory memory = memoryRepository.save(MemoryFixture.create(LocalDate.of(2023, 12, 31), LocalDate.of(2024, 1, 10)));
Moment moment1 = momentRepository.save(MomentFixture
Expand All @@ -40,8 +41,7 @@ void deleteAllByMomentIdInBatch() {
.createWithImages(memory, LocalDateTime.of(2023, 12, 31, 22, 20), new MomentImages(List.of("url1", "url2"))));

// when
momentImageRepository.deleteAllByMomentIdInBatch(List.of(moment1.getId(), moment2.getId()));
em.flush();
momentImageRepository.deleteAllByMomentIdInBulk(List.of(moment1.getId(), moment2.getId()));
em.clear();

// then
Expand All @@ -53,4 +53,25 @@ void deleteAllByMomentIdInBatch() {
.isNotEmpty()).isFalse()
);
}

@DisplayName("특정 스타카토 이미지들을 벌크 삭제한다.")
@Test
void deleteAllByIdInBulk() {
// given
Memory memory = memoryRepository.save(MemoryFixture.create(LocalDate.of(2023, 12, 31), LocalDate.of(2024, 1, 10)));
MomentImages momentImages = new MomentImages(List.of("url1", "url2", "url3"));
Moment moment = momentRepository.save(MomentFixture.createWithImages(memory, LocalDateTime.of(2023, 12, 31, 22, 20), momentImages));

List<Long> imageIds = moment.getMomentImages()
.getImages()
.stream()
.map(MomentImage::getId)
.toList();

// when
momentImageRepository.deleteAllByIdInBulk(imageIds);

// then
assertThat(momentImageRepository.findAll()).isEmpty();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ void findAllByMemory_MemoryMembers_Member() {

@DisplayName("특정 추억의 id를 가진 모든 스타카토를 삭제한다.")
@Test
void deleteAllByMemoryIdInBatch() {
void deleteAllByMemoryIdInBulk() {
// given
Member member = memberRepository.save(MemberFixture.create());
Memory memory = memoryRepository.save(MemoryFixture.create(LocalDate.of(2023, 12, 31), LocalDate.of(2024, 1, 10)));
Expand All @@ -80,7 +80,7 @@ void deleteAllByMemoryIdInBatch() {
Moment moment2 = momentRepository.save(MomentFixture.create(memory, LocalDateTime.of(2024, 1, 1, 22, 21)));

// when
momentRepository.deleteAllByMemoryIdInBatch(memory.getId());
momentRepository.deleteAllByMemoryIdInBulk(memory.getId());
entityManager.flush();
entityManager.clear();

Expand Down
Loading

0 comments on commit 4cf2d6f

Please sign in to comment.