diff --git a/src/main/java/com/jiwon/mylog/domain/post/entity/Post.java b/src/main/java/com/jiwon/mylog/domain/post/entity/Post.java index e4b3029..353ce56 100644 --- a/src/main/java/com/jiwon/mylog/domain/post/entity/Post.java +++ b/src/main/java/com/jiwon/mylog/domain/post/entity/Post.java @@ -79,7 +79,7 @@ public class Post extends BaseEntity { private List images = new ArrayList<>(); @Builder.Default - @OneToMany(mappedBy = "post") + @OneToMany(mappedBy = "post", cascade = CascadeType.ALL, orphanRemoval = true) private List postTags = new ArrayList<>(); @Builder.Default @@ -112,12 +112,12 @@ public void update(PostRequest request, Category category, List tags) { } private void updateTags(List tags) { - this.postTags.clear(); - this.postTags.addAll( - tags.stream() - .map(tag -> PostTag.createPostTag(this, tag)) - .toList() - ); + this.postTags.removeIf(pt -> !tags.contains(pt.getTag())); + for (Tag tag : tags) { + if (postTags.stream().noneMatch(pt -> pt.getTag().equals(tag))) { + postTags.add(PostTag.createPostTag(this, tag)); + } + } } public void delete() { diff --git a/src/main/java/com/jiwon/mylog/domain/tag/entity/PostTag.java b/src/main/java/com/jiwon/mylog/domain/tag/entity/PostTag.java index dcecacc..412e555 100644 --- a/src/main/java/com/jiwon/mylog/domain/tag/entity/PostTag.java +++ b/src/main/java/com/jiwon/mylog/domain/tag/entity/PostTag.java @@ -7,12 +7,21 @@ import jakarta.persistence.GenerationType; import jakarta.persistence.Id; import jakarta.persistence.ManyToOne; +import jakarta.persistence.Table; +import jakarta.persistence.UniqueConstraint; import lombok.Getter; import lombok.Setter; @Getter @Setter @Entity +@Table( + name = "post_tag", + uniqueConstraints = @UniqueConstraint( + name = "post_tag_uk", + columnNames = {"post_id", "tag_id"} + ) +) public class PostTag { @Id diff --git a/src/main/java/com/jiwon/mylog/global/redis/RedisUtil.java b/src/main/java/com/jiwon/mylog/global/redis/RedisUtil.java index 6f0522b..f6a7d39 100644 --- a/src/main/java/com/jiwon/mylog/global/redis/RedisUtil.java +++ b/src/main/java/com/jiwon/mylog/global/redis/RedisUtil.java @@ -1,5 +1,6 @@ package com.jiwon.mylog.global.redis; +import com.jiwon.mylog.global.redis.key.RedisKey; import java.time.Duration; import java.time.LocalDate; import java.time.format.DateTimeParseException; @@ -111,11 +112,11 @@ public void addPostViewUser(String key, String value) { redisTemplate.expire(key, Duration.ofHours(12)); } - public Map getAllPostView(String keyPrefix) { - Set keys = redisTemplate.keys(keyPrefix); + public Map getAllPostView(RedisKey keyPattern) { + Set keys = redisTemplate.keys(keyPattern.getPrefix() + "*"); return keys.stream() .collect(Collectors.toMap( - key -> Long.parseLong(key.replace(keyPrefix, "")), + key -> keyPattern.getUserIdentifier(key), key -> getInt(key, 0) )); } diff --git a/src/main/java/com/jiwon/mylog/global/redis/key/RedisKey.java b/src/main/java/com/jiwon/mylog/global/redis/key/RedisKey.java index 12ba0cf..76ce0e3 100644 --- a/src/main/java/com/jiwon/mylog/global/redis/key/RedisKey.java +++ b/src/main/java/com/jiwon/mylog/global/redis/key/RedisKey.java @@ -30,6 +30,12 @@ public String getPrefix() { return prefix; } + public Long getUserIdentifier(String redisKey) { + int index = redisKey.lastIndexOf(':'); + String keyString = redisKey.substring(index + 1); + return Long.parseLong(keyString); + } + public Duration getTtl() { return ttl; } diff --git a/src/main/java/com/jiwon/mylog/global/schedular/PostViewScheduler.java b/src/main/java/com/jiwon/mylog/global/schedular/PostViewScheduler.java index cd4ddc4..150e45f 100644 --- a/src/main/java/com/jiwon/mylog/global/schedular/PostViewScheduler.java +++ b/src/main/java/com/jiwon/mylog/global/schedular/PostViewScheduler.java @@ -19,15 +19,18 @@ public class PostViewScheduler { private final PostRepository postRepository; private final RedisUtil redisUtil; - @Scheduled(fixedRate = 10 * 60 * 1000L) + @Scheduled(fixedRate = 30 * 60 * 1000L) @Transactional public void syncPostViewToDB() { - Map postCounts = redisUtil.getAllPostView(RedisKey.VIEW_COUNT_KEY.getPrefix()); + Map postCounts = redisUtil.getAllPostView(RedisKey.VIEW_COUNT_KEY); + log.info("PostViewScheduler 시작: {}개", postCounts.size()); + postCounts.forEach((postId, view) -> { try { + log.debug("postId: {}, view: {}", postId, view); postRepository.updatePostView(postId, view); } catch (Exception e) { - log.error("조회수 동기화 실패, 게시글 {}: {}", postId, e.getMessage()); + log.error("조회수 동기화 실패, postId={}: {}", postId, e.getMessage()); } }); }