Skip to content

Commit

Permalink
[BE] Stage 생성, 수정, 삭제 시 발생하는 비효율적인 쿼리 개선 (#988) (#991)
Browse files Browse the repository at this point in the history
* feat: Staga에 `@OneToMany` 관계의 List<StageArtist> 필드 추가

* refactor: StageArtistRepository 의존 제거
  • Loading branch information
seokjin8678 authored May 30, 2024
1 parent 9109569 commit 4c9a07f
Show file tree
Hide file tree
Showing 25 changed files with 310 additions and 416 deletions.
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package com.festago.admin.application;

import com.festago.admin.repository.AdminFestivalIdResolverQueryDslRepository;
import com.festago.admin.repository.AdminStageIdResolverQueryDslRepository;
import com.festago.admin.repository.AdminStageResolverQueryDslRepository;
import com.festago.festival.application.FestivalQueryInfoArtistRenewService;
import com.festago.stage.application.StageQueryInfoService;
import java.time.LocalDate;
Expand All @@ -19,20 +19,20 @@ public class AdminQueryInfoRenewalService {

private final FestivalQueryInfoArtistRenewService festivalQueryInfoArtistRenewService;
private final StageQueryInfoService stageQueryInfoService;
private final AdminStageIdResolverQueryDslRepository adminStageIdResolverQueryDslRepository;
private final AdminStageResolverQueryDslRepository adminStageResolverQueryDslRepository;
private final AdminFestivalIdResolverQueryDslRepository adminFestivalIdResolverQueryDslRepository;

public void renewalByFestivalId(Long festivalId) {
festivalQueryInfoArtistRenewService.renewArtistInfo(festivalId);
adminStageIdResolverQueryDslRepository.findStageIdsByFestivalId(festivalId)
adminStageResolverQueryDslRepository.findStageByFestivalId(festivalId)
.forEach(stageQueryInfoService::renewalStageQueryInfo);
}

public void renewalByFestivalStartDatePeriod(LocalDate to, LocalDate end) {
List<Long> festivalIds = adminFestivalIdResolverQueryDslRepository.findFestivalIdsByStartDatePeriod(to, end);
log.info("{}개의 축제에 대해 QueryInfo를 새로 갱신합니다.", festivalIds.size());
festivalIds.forEach(festivalQueryInfoArtistRenewService::renewArtistInfo);
adminStageIdResolverQueryDslRepository.findStageIdsByFestivalIdIn(festivalIds)
adminStageResolverQueryDslRepository.findStageByFestivalIdIn(festivalIds)
.forEach(stageQueryInfoService::renewalStageQueryInfo);
}
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package com.festago.admin.repository;

import static com.festago.festival.domain.QFestival.festival;
import static com.festago.stage.domain.QStage.stage;

import com.festago.common.querydsl.QueryDslRepositorySupport;
import com.festago.stage.domain.Stage;
import java.util.List;
import org.springframework.stereotype.Repository;

@Repository
public class AdminStageResolverQueryDslRepository extends QueryDslRepositorySupport {

public AdminStageResolverQueryDslRepository() {
super(Stage.class);
}

public List<Stage> findStageByFestivalId(Long festivalId) {
return selectFrom(stage)
.innerJoin(stage.festival)
.leftJoin(stage.artists).fetchJoin()
.where(festival.id.eq(festivalId))
.fetch();
}

public List<Stage> findStageByFestivalIdIn(List<Long> festivalIds) {
return selectFrom(stage)
.innerJoin(stage.festival)
.leftJoin(stage.artists).fetchJoin()
.where(festival.id.in(festivalIds))
.fetch();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,14 @@ public class StageQueryInfoEventListener {
@Transactional(propagation = Propagation.MANDATORY)
public void stageCreatedEventHandler(StageCreatedEvent event) {
Stage stage = event.stage();
stageQueryInfoService.initialStageQueryInfo(stage.getId());
stageQueryInfoService.initialStageQueryInfo(stage);
}

@EventListener
@Transactional(propagation = Propagation.MANDATORY)
public void stageUpdatedEventHandler(StageUpdatedEvent event) {
Stage stage = event.stage();
stageQueryInfoService.renewalStageQueryInfo(stage.getId());
stageQueryInfoService.renewalStageQueryInfo(stage);
}

@EventListener
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,11 @@
import com.festago.artist.domain.ArtistsSerializer;
import com.festago.artist.repository.ArtistRepository;
import com.festago.common.exception.ErrorCode;
import com.festago.common.exception.InternalServerException;
import com.festago.common.exception.NotFoundException;
import com.festago.stage.domain.Stage;
import com.festago.stage.domain.StageQueryInfo;
import com.festago.stage.repository.StageArtistRepository;
import com.festago.stage.repository.StageQueryInfoRepository;
import java.util.List;
import java.util.Set;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
Expand All @@ -23,30 +21,19 @@
public class StageQueryInfoService {

private final StageQueryInfoRepository stageQueryInfoRepository;
private final StageArtistRepository stageArtistRepository;
private final ArtistRepository artistRepository;
private final ArtistsSerializer serializer;

public void initialStageQueryInfo(Long stageId) {
List<Artist> artists = getStageArtists(stageId);
StageQueryInfo stageQueryInfo = StageQueryInfo.of(stageId, artists, serializer);
public void initialStageQueryInfo(Stage stage) {
List<Artist> artists = artistRepository.findByIdIn(stage.getArtistIds());
StageQueryInfo stageQueryInfo = StageQueryInfo.of(stage.getId(), artists, serializer);
stageQueryInfoRepository.save(stageQueryInfo);
}

private List<Artist> getStageArtists(Long stageId) {
Set<Long> artistIds = stageArtistRepository.findAllArtistIdByStageId(stageId);
List<Artist> artists = artistRepository.findByIdIn(artistIds);
if (artists.size() != artistIds.size()) {
log.error("StageArtist에 존재하지 않은 Artist가 있습니다. artistsIds=" + artistIds);
throw new InternalServerException(ErrorCode.ARTIST_NOT_FOUND);
}
return artists;
}

public void renewalStageQueryInfo(Long stageId) {
StageQueryInfo stageQueryInfo = stageQueryInfoRepository.findByStageId(stageId)
public void renewalStageQueryInfo(Stage stage) {
StageQueryInfo stageQueryInfo = stageQueryInfoRepository.findByStageId(stage.getId())
.orElseThrow(() -> new NotFoundException(ErrorCode.STAGE_NOT_FOUND));
List<Artist> artists = getStageArtists(stageId);
List<Artist> artists = artistRepository.findByIdIn(stage.getArtistIds());
stageQueryInfo.updateArtist(artists, serializer);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,8 @@
import com.festago.festival.domain.Festival;
import com.festago.festival.repository.FestivalRepository;
import com.festago.stage.domain.Stage;
import com.festago.stage.domain.StageArtist;
import com.festago.stage.dto.command.StageCreateCommand;
import com.festago.stage.dto.event.StageCreatedEvent;
import com.festago.stage.repository.StageArtistRepository;
import com.festago.stage.repository.StageRepository;
import java.util.List;
import lombok.RequiredArgsConstructor;
Expand All @@ -28,7 +26,6 @@ public class StageCreateService {
private final StageRepository stageRepository;
private final FestivalRepository festivalRepository;
private final ArtistRepository artistRepository;
private final StageArtistRepository stageArtistRepository;
private final ApplicationEventPublisher eventPublisher;

public Long createStage(StageCreateCommand command) {
Expand All @@ -40,7 +37,7 @@ public Long createStage(StageCreateCommand command) {
festival
));
List<Long> artistIds = command.artistIds();
createStageArtist(artistIds, stage);
stage.renewArtists(artistIds);
eventPublisher.publishEvent(new StageCreatedEvent(stage));
return stage.getId();
}
Expand All @@ -49,12 +46,7 @@ private void validate(StageCreateCommand command) {
List<Long> artistIds = command.artistIds();
Validator.maxSize(artistIds, MAX_ARTIST_SIZE, "artistIds");
Validator.notDuplicate(artistIds, "artistIds");
}

private void createStageArtist(List<Long> artistIds, Stage stage) {
if (artistRepository.countByIdIn(artistIds) == artistIds.size()) {
artistIds.forEach(artistId -> stageArtistRepository.save(new StageArtist(stage.getId(), artistId)));
} else {
if (artistRepository.countByIdIn(artistIds) != artistIds.size()) {
throw new NotFoundException(ErrorCode.ARTIST_NOT_FOUND);
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package com.festago.stage.application.command;

import com.festago.stage.dto.event.StageDeletedEvent;
import com.festago.stage.repository.StageArtistRepository;
import com.festago.stage.repository.StageRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.context.ApplicationEventPublisher;
Expand All @@ -14,12 +13,10 @@
public class StageDeleteService {

private final StageRepository stageRepository;
private final StageArtistRepository stageArtistRepository;
private final ApplicationEventPublisher eventPublisher;

public void deleteStage(Long stageId) {
stageRepository.findByIdWithFetch(stageId).ifPresent(stage -> {
stageArtistRepository.deleteByStageId(stageId);
stageRepository.findById(stageId).ifPresent(stage -> {
stageRepository.deleteById(stageId);
eventPublisher.publishEvent(new StageDeletedEvent(stage));
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,8 @@
import com.festago.common.exception.NotFoundException;
import com.festago.common.util.Validator;
import com.festago.stage.domain.Stage;
import com.festago.stage.domain.StageArtist;
import com.festago.stage.dto.command.StageUpdateCommand;
import com.festago.stage.dto.event.StageUpdatedEvent;
import com.festago.stage.repository.StageArtistRepository;
import com.festago.stage.repository.StageRepository;
import java.time.LocalDateTime;
import java.util.List;
Expand All @@ -26,7 +24,6 @@ public class StageUpdateService {

private final StageRepository stageRepository;
private final ArtistRepository artistRepository;
private final StageArtistRepository stageArtistRepository;
private final ApplicationEventPublisher eventPublisher;

public void updateStage(Long stageId, StageUpdateCommand command) {
Expand All @@ -37,21 +34,16 @@ public void updateStage(Long stageId, StageUpdateCommand command) {
Stage stage = stageRepository.findByIdWithFetch(stageId)
.orElseThrow(() -> new NotFoundException(ErrorCode.STAGE_NOT_FOUND));
stage.changeTime(startTime, ticketOpenTime);
renewStageArtist(stage, artistIds);
stage.renewArtists(artistIds);
eventPublisher.publishEvent(new StageUpdatedEvent(stage));
}

private void validate(StageUpdateCommand command) {
List<Long> artistIds = command.artistIds();
Validator.maxSize(artistIds, MAX_ARTIST_SIZE, "artistIds");
Validator.notDuplicate(artistIds, "artistIds");
}

private void renewStageArtist(Stage stage, List<Long> artistIds) {
if (artistRepository.countByIdIn(artistIds) != artistIds.size()) {
throw new NotFoundException(ErrorCode.ARTIST_NOT_FOUND);
}
stageArtistRepository.deleteByStageId(stage.getId());
artistIds.forEach(artistId -> stageArtistRepository.save(new StageArtist(stage.getId(), artistId)));
}
}

This file was deleted.

25 changes: 24 additions & 1 deletion backend/src/main/java/com/festago/stage/domain/Stage.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import com.festago.common.util.Validator;
import com.festago.festival.domain.Festival;
import com.festago.ticket.domain.Ticket;
import jakarta.persistence.CascadeType;
import jakarta.persistence.Entity;
import jakarta.persistence.FetchType;
import jakarta.persistence.GeneratedValue;
Expand All @@ -17,6 +18,8 @@
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;

Expand All @@ -41,7 +44,8 @@ public class Stage extends BaseTimeEntity {
@OneToMany(mappedBy = "stage", fetch = FetchType.LAZY)
private List<Ticket> tickets = new ArrayList<>();

@OneToMany(fetch = FetchType.LAZY, mappedBy = "stageId")
@OneToMany(fetch = FetchType.LAZY, mappedBy = "stageId", orphanRemoval = true,
cascade = {CascadeType.PERSIST, CascadeType.REMOVE})
private List<StageArtist> artists = new ArrayList<>();

public Stage(LocalDateTime startTime, LocalDateTime ticketOpenTime, Festival festival) {
Expand Down Expand Up @@ -87,6 +91,25 @@ public void changeTime(LocalDateTime startTime, LocalDateTime ticketOpenTime) {
this.ticketOpenTime = ticketOpenTime;
}

public void renewArtists(List<Long> artistIds) {
artists.removeIf(artist -> !artistIds.contains(artist.getArtistId()));
Set<Long> existsArtistIds = artists.stream()
.map(StageArtist::getArtistId)
.collect(Collectors.toSet());
for (Long artistId : artistIds) {
if (!existsArtistIds.contains(artistId)) {
artists.add(new StageArtist(this.id, artistId));
}
}
}

public List<Long> getArtistIds() {
return artists.stream()
.map(StageArtist::getArtistId)
.sorted()
.toList();
}

public Long getId() {
return id;
}
Expand Down
Loading

0 comments on commit 4c9a07f

Please sign in to comment.