diff --git a/backend/src/main/java/com/openisle/service/PostService.java b/backend/src/main/java/com/openisle/service/PostService.java index 69c071a92..2fd987513 100644 --- a/backend/src/main/java/com/openisle/service/PostService.java +++ b/backend/src/main/java/com/openisle/service/PostService.java @@ -24,6 +24,7 @@ import com.openisle.model.Role; import com.openisle.exception.RateLimitException; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.ApplicationContext; import org.springframework.stereotype.Service; import org.springframework.scheduling.TaskScheduler; import com.openisle.service.EmailSender; @@ -34,7 +35,6 @@ import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Sort; import org.springframework.transaction.annotation.Transactional; -import java.time.ZoneId; import java.time.LocalDateTime; import java.util.ArrayList; import java.util.Collections; @@ -65,6 +65,7 @@ public class PostService { private final ImageUploader imageUploader; private final TaskScheduler taskScheduler; private final EmailSender emailSender; + private final ApplicationContext applicationContext; private final ConcurrentMap> scheduledFinalizations = new ConcurrentHashMap<>(); @org.springframework.beans.factory.annotation.Autowired @@ -84,6 +85,7 @@ public class PostService { ImageUploader imageUploader, TaskScheduler taskScheduler, EmailSender emailSender, + ApplicationContext applicationContext, @Value("${app.post.publish-mode:DIRECT}") PublishMode publishMode) { this.postRepository = postRepository; this.userRepository = userRepository; @@ -101,6 +103,7 @@ public class PostService { this.imageUploader = imageUploader; this.taskScheduler = taskScheduler; this.emailSender = emailSender; + this.applicationContext = applicationContext; this.publishMode = publishMode; } @@ -109,12 +112,12 @@ public class PostService { LocalDateTime now = LocalDateTime.now(); for (LotteryPost lp : lotteryPostRepository.findByEndTimeAfterAndWinnersIsEmpty(now)) { ScheduledFuture future = taskScheduler.schedule( - () -> finalizeLottery(lp.getId()), + () -> applicationContext.getBean(PostService.class).finalizeLottery(lp.getId()), java.util.Date.from(java.sql.Timestamp.valueOf(lp.getEndTime()).toInstant())); scheduledFinalizations.put(lp.getId(), future); } for (LotteryPost lp : lotteryPostRepository.findByEndTimeBeforeAndWinnersIsEmpty(now)) { - finalizeLottery(lp.getId()); + applicationContext.getBean(PostService.class).finalizeLottery(lp.getId()); } } @@ -209,7 +212,7 @@ public class PostService { if (post instanceof LotteryPost lp && lp.getEndTime() != null) { ScheduledFuture future = taskScheduler.schedule( - () -> finalizeLottery(lp.getId()), + () -> applicationContext.getBean(PostService.class).finalizeLottery(lp.getId()), java.util.Date.from(java.sql.Timestamp.valueOf(lp.getEndTime()).toInstant())); scheduledFinalizations.put(lp.getId(), future); } @@ -225,7 +228,8 @@ public class PostService { lotteryPostRepository.save(post); } - private void finalizeLottery(Long postId) { + @Transactional + public void finalizeLottery(Long postId) { log.info("start to finalizeLottery for {}", postId); scheduledFinalizations.remove(postId); lotteryPostRepository.findById(postId).ifPresent(lp -> { diff --git a/backend/src/test/java/com/openisle/service/PostServiceTest.java b/backend/src/test/java/com/openisle/service/PostServiceTest.java index 5762f213f..315fd0fb2 100644 --- a/backend/src/test/java/com/openisle/service/PostServiceTest.java +++ b/backend/src/test/java/com/openisle/service/PostServiceTest.java @@ -5,6 +5,7 @@ import com.openisle.repository.*; import com.openisle.exception.RateLimitException; import org.junit.jupiter.api.Test; import org.springframework.scheduling.TaskScheduler; +import org.springframework.context.ApplicationContext; import static org.junit.jupiter.api.Assertions.*; @@ -32,11 +33,13 @@ class PostServiceTest { ImageUploader imageUploader = mock(ImageUploader.class); TaskScheduler taskScheduler = mock(TaskScheduler.class); EmailSender emailSender = mock(EmailSender.class); + ApplicationContext context = mock(ApplicationContext.class); PostService service = new PostService(postRepo, userRepo, catRepo, tagRepo, lotteryRepo, notifService, subService, commentService, commentRepo, reactionRepo, subRepo, notificationRepo, postReadService, - imageUploader, taskScheduler, emailSender, PublishMode.DIRECT); + imageUploader, taskScheduler, emailSender, context, PublishMode.DIRECT); + when(context.getBean(PostService.class)).thenReturn(service); Post post = new Post(); post.setId(1L); @@ -76,11 +79,13 @@ class PostServiceTest { ImageUploader imageUploader = mock(ImageUploader.class); TaskScheduler taskScheduler = mock(TaskScheduler.class); EmailSender emailSender = mock(EmailSender.class); + ApplicationContext context = mock(ApplicationContext.class); PostService service = new PostService(postRepo, userRepo, catRepo, tagRepo, lotteryRepo, notifService, subService, commentService, commentRepo, reactionRepo, subRepo, notificationRepo, postReadService, - imageUploader, taskScheduler, emailSender, PublishMode.DIRECT); + imageUploader, taskScheduler, emailSender, context, PublishMode.DIRECT); + when(context.getBean(PostService.class)).thenReturn(service); when(postRepo.countByAuthorAfter(eq("alice"), any())).thenReturn(1L);