Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -96,10 +96,9 @@ public ApiResponse<SeedResponse.GetAllSeeds> getCategorySeeds(
schema = @Schema(implementation = SeedResponse.SeedDetail.class))),
@io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "500", description = "서버 오류")
})
public ApiResponse<SeedResponse.SeedDetail> getSeedDetail(@PathVariable("seedId") Long seedId,
@AuthenticationPrincipal CustomUserDetails customUserDetails) {

Member member = customUserDetails.getMember();
public ApiResponse<SeedResponse.SeedDetail> getSeedDetail(
@PathVariable("seedId") Long seedId,
@AuthenticationPrincipal CustomUserDetails customUserDetails) {

return new ApiResponse<>(seedService.getSeedDetail(seedId));
}
Expand Down Expand Up @@ -300,10 +299,11 @@ public ApiResponse<SeedResponse.GetAllSeeds> getUnreadSeeds(
@io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "500", description = "서버 오류")
})
public ApiResponse<Void> deleteSeedList(
@RequestBody @Valid SeedDeleteListRequest request,
@RequestParam List<Long> ids,
@AuthenticationPrincipal CustomUserDetails customUserDetails) {

Member member = customUserDetails.getMember();
seedService.deleteSeedList(request, member);
seedService.deleteSeedList(ids, member);
return new ApiResponse<>(ErrorCode.REQUEST_OK);
}

Expand Down
5 changes: 4 additions & 1 deletion src/main/java/com/adoonge/seedzip/seed/domain/Seed.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import jakarta.persistence.ManyToOne;
import jakarta.persistence.OneToMany;
import jakarta.persistence.Table;
import jakarta.persistence.Version;
import java.time.LocalDate;
import java.util.HashSet;
import java.util.Set;
Expand Down Expand Up @@ -59,6 +60,9 @@ public class Seed extends BaseEntity {
@Column(name = "view_count", nullable = false)
private long viewCount = 0L; // 조회수

@Version
private Long version;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "member_id")
@OnDelete(action = OnDeleteAction.CASCADE) // Member 삭제 시 Content도 삭제
Expand All @@ -73,7 +77,6 @@ public class Seed extends BaseEntity {
@OneToMany(mappedBy = "seed", fetch = FetchType.LAZY)
private Set<CategorySeed> categorySeeds = new HashSet<>();


public void updateSeedName(String seedName) {
this.seedName = seedName;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,4 +48,13 @@ default void deleteUnreferencedContents() {}
List<Seed> findAllByIdIn(List<Long> seedIds);

void deleteAllByIdIn(List<Long> seedIds);

@Modifying
@Query("""
UPDATE Seed s
SET s.viewCount = s.viewCount + 1,
s.version = s.version + 1
WHERE s.id = :id AND s.version = :version
""")
int increaseViewCount(@Param("id") Long id, @Param("version") Long version);
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,6 @@ public SeedCacheService(RedisTemplate<String, Object> redisTemplate) {
this.redisTemplate = redisTemplate;
}

public void increaseViewCounts(Long seedId) {
redisTemplate.opsForHash().increment(SEED_VIEWS_KEY, seedId.toString(), 1);
}

public Map<Object, Object> getAllViewCounts() {
return redisTemplate.opsForHash().entries(SEED_VIEWS_KEY);
}
Expand Down

This file was deleted.

30 changes: 18 additions & 12 deletions src/main/java/com/adoonge/seedzip/seed/service/SeedService.java
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,6 @@
public class SeedService {

private final FileService fileService;
private final SeedCacheService seedCacheService;

private final SeedRepository seedRepository;
private final FileRepository fileRepository;
Expand Down Expand Up @@ -172,10 +171,18 @@ public void uploadFiles(Long seedId, List<MultipartFile> files) {
fileService.saveFiles(files, seed);
}

@Transactional(readOnly = true)
@Transactional
public SeedResponse.SeedDetail getSeedDetail(Long seedId) {
Seed seed = getSeedOrThrow(seedId);
seedCacheService.increaseViewCounts(seedId);

// 최대 3회 재시도
for (int i = 0; i < 3; i++) {
int updated = seedRepository.increaseViewCount(seedId, seed.getVersion());
if (updated > 0) break; // 성공
// 실패면 최신 버전 재조회 후 재시도
seed = getSeedOrThrow(seedId);
}

List<File> files = fileRepository.findAllBySeed(seed)
.orElseThrow(() -> SeedzipException.from(ErrorCode.FILE_NOT_FOUND));

Expand Down Expand Up @@ -449,12 +456,11 @@ public SeedResponse.GetAllSeeds getUnreadSeeds(Member member, int page, int size
}

@Transactional
public void deleteSeedList(SeedDeleteListRequest request, Member member) {
List<Long> seedIds = request.seedIdList();
if (seedIds.isEmpty()) return;
public void deleteSeedList(List<Long> ids, Member member) {
if (ids.isEmpty()) return;

List<Seed> seeds = seedRepository.findAllByIdIn(seedIds);
if(seedIds.size() != seeds.size()) {
List<Seed> seeds = seedRepository.findAllByIdIn(ids);
if(ids.size() != seeds.size()) {
throw SeedzipException.from(ErrorCode.SEED_ACCESS_DENIED);
}

Expand All @@ -466,10 +472,10 @@ public void deleteSeedList(SeedDeleteListRequest request, Member member) {
deleteFileFromS3(seed.getId(), seed);
}

categorySeedRepository.deleteAllBySeedIdIn(seedIds);
fileRepository.deleteAllBySeedIdIn(seedIds);
seedTagRepository.deleteAllBySeedIdIn(seedIds);
seedRepository.deleteAllByIdIn(seedIds);
categorySeedRepository.deleteAllBySeedIdIn(ids);
fileRepository.deleteAllBySeedIdIn(ids);
seedTagRepository.deleteAllBySeedIdIn(ids);
seedRepository.deleteAllByIdIn(ids);
}

private void deleteFileFromS3(Long id, Seed seed) {
Expand Down