Skip to content

Commit cc680eb

Browse files
committed
feat: Interest 삭제 시 Article 논리적 삭제로 변경
- Interest 엔티티에 소프트 삭제 지원 추가 (@SQLDelete, @SQLRestriction) - is_deleted, deleted_at, updated_at 컬럼 추가 - FK 제약조건 ON DELETE CASCADE 제거 (schema.sql, schema-h2.sql) - InterestService.removeInterest()에서 연결된 Article들 소프트 삭제 처리 - ArticleRepository.findAllByInterestId() 메서드 추가
1 parent 7e357cc commit cc680eb

5 files changed

Lines changed: 42 additions & 8 deletions

File tree

monew/src/main/java/com/spring/monew/article/repository/ArticleRepository.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,4 +37,6 @@ public interface ArticleRepository extends JpaRepository<Article, UUID>, Article
3737
AND deleted_at < :threshold
3838
""", nativeQuery = true)
3939
List<UUID> findSoftDeletedBefore(@Param("threshold") Instant threshold);
40+
41+
List<Article> findAllByInterestId(UUID interestId);
4042
}

monew/src/main/java/com/spring/monew/interest/domain/Interest.java

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,16 +16,21 @@
1616
import lombok.NoArgsConstructor;
1717
import org.hibernate.annotations.ColumnDefault;
1818
import org.hibernate.annotations.CreationTimestamp;
19+
import org.hibernate.annotations.SQLDelete;
20+
import org.hibernate.annotations.SQLRestriction;
21+
import org.hibernate.annotations.UpdateTimestamp;
1922
import org.jetbrains.annotations.TestOnly;
2023

2124
@Entity
2225
@Table(name = "interests")
2326
@NoArgsConstructor(access = AccessLevel.PROTECTED)
2427
@Getter
28+
@SQLDelete(sql = "UPDATE interests SET is_deleted = true, deleted_at = CURRENT_TIMESTAMP WHERE id = ?")
29+
@SQLRestriction("is_deleted = false")
2530
public class Interest {
2631

2732
@Id
28-
@GeneratedValue(strategy = GenerationType.UUID) //PK 자동 삽입
33+
@GeneratedValue(strategy = GenerationType.UUID)
2934
private UUID id;
3035

3136
@Column(nullable = false, unique = true)
@@ -35,23 +40,33 @@ public class Interest {
3540
@Column(nullable = false, columnDefinition = "TEXT")
3641
private List<String> keywords;
3742

38-
/** DB TEXT(JSON) 직접 검색용: QueryDSL에서만 사용 */
3943
@Column(name = "keywords", insertable = false, updatable = false)
4044
private String keywordsString;
4145

4246
@Column(name = "created_at", nullable = false, updatable = false)
4347
@CreationTimestamp
4448
private Instant createdAt;
4549

50+
@Column(name = "updated_at", nullable = false)
51+
@UpdateTimestamp
52+
private Instant updatedAt;
53+
4654
@Column(name = "subscriptions_count", nullable = false)
4755
@ColumnDefault("0")
4856
private long subscriptionsCount;
4957

58+
@Column(name = "is_deleted", nullable = false)
59+
@ColumnDefault("false")
60+
private boolean isDeleted = false;
61+
62+
@Column(name = "deleted_at")
63+
private Instant deletedAt;
64+
5065
public Interest(String name, List<String> keywords) {
5166
this.name = name;
5267
this.keywords = keywords;
5368
this.createdAt = Instant.now();
54-
this.subscriptionsCount = 0L; // 기본값 설정
69+
this.subscriptionsCount = 0L;
5570
}
5671

5772
public void update(List<String> keywords) {
@@ -68,7 +83,6 @@ public void decrementSubscriptionsCount() {
6883
}
6984
}
7085

71-
// 테스트 용
7286
@TestOnly
7387
public Interest(UUID id, String name, List<String> keywords, String keywordsString,
7488
Instant createdAt, long subscriptionsCount) {

monew/src/main/java/com/spring/monew/interest/service/impl/InterestServiceImpl.java

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package com.spring.monew.interest.service.impl;
22

3+
import com.spring.monew.article.domain.Article;
4+
import com.spring.monew.article.repository.ArticleRepository;
35
import com.spring.monew.interest.controller.dto.request.InterestRegisterRequest;
46
import com.spring.monew.interest.controller.dto.request.InterestUpdateRequest;
57
import com.spring.monew.interest.controller.dto.response.CursorPageResponseInterestDto;
@@ -12,22 +14,24 @@
1214
import java.util.NoSuchElementException;
1315
import java.util.UUID;
1416
import lombok.RequiredArgsConstructor;
17+
import lombok.extern.slf4j.Slf4j;
1518
import org.springframework.stereotype.Service;
1619
import org.springframework.transaction.annotation.Transactional;
1720

21+
@Slf4j
1822
@Service
1923
@Transactional
2024
@RequiredArgsConstructor
2125
public class InterestServiceImpl implements InterestService {
2226

2327
private final InterestRepository interestRepository;
28+
private final ArticleRepository articleRepository;
2429

2530
@Override
2631
@Transactional
2732
public InterestDto addInterest(InterestRegisterRequest registerRequest) {
2833
List<String> similarNames = interestRepository.findSimilarNames(registerRequest.name(), 0.45);
2934

30-
//예외 처리 필요 interests name exixsts
3135
if (interestRepository.existsByName(registerRequest.name())) {
3236
throw new IllegalArgumentException("같은 이름이 존재합니다.");
3337
}
@@ -85,6 +89,14 @@ public void removeInterest(UUID interestId) {
8589
Interest interest = interestRepository.findById(interestId)
8690
.orElseThrow(() -> new NoSuchElementException("존재하지 않는 관심사입니다."));
8791

92+
List<Article> relatedArticles = articleRepository.findAllByInterestId(interestId);
93+
94+
if (!relatedArticles.isEmpty()) {
95+
log.info("관심사 삭제로 인한 연관 게시글 소프트 삭제: interestId={}, articleCount={}",
96+
interestId, relatedArticles.size());
97+
articleRepository.deleteAll(relatedArticles);
98+
}
99+
88100
interestRepository.delete(interest);
89101
}
90102
}

monew/src/main/resources/schema-h2.sql

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,10 @@ CREATE TABLE interests (
2020
name VARCHAR(255) NOT NULL UNIQUE,
2121
created_at TIMESTAMP NOT NULL,
2222
keywords TEXT NOT NULL,
23-
subscriptions_count BIGINT NOT NULL DEFAULT 0
23+
subscriptions_count BIGINT NOT NULL DEFAULT 0,
24+
updated_at TIMESTAMP NOT NULL,
25+
is_deleted BOOLEAN NOT NULL DEFAULT FALSE,
26+
deleted_at TIMESTAMP
2427
);
2528

2629
-- ==============================

monew/src/main/resources/schema.sql

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,10 @@ CREATE TABLE interests
6464
name VARCHAR(255) NOT NULL UNIQUE,
6565
created_at TIMESTAMP WITH TIME ZONE NOT NULL,
6666
keywords TEXT NOT NULL,
67-
subscriptions_count BIGINT NOT NULL DEFAULT 0
67+
subscriptions_count BIGINT NOT NULL DEFAULT 0,
68+
updated_at TIMESTAMP WITH TIME ZONE NOT NULL,
69+
is_deleted BOOLEAN NOT NULL DEFAULT FALSE,
70+
deleted_at TIMESTAMP WITH TIME ZONE
6871
);
6972

7073
-- name 컬럼 GIN 트라이그램 인덱스
@@ -107,7 +110,7 @@ CREATE TABLE articles
107110
deleted_at TIMESTAMP WITH TIME ZONE NULL,
108111
CONSTRAINT fk_article_interest FOREIGN KEY (interest_id)
109112
REFERENCES interests (id)
110-
ON DELETE CASCADE ON UPDATE CASCADE
113+
ON UPDATE CASCADE
111114
);
112115

113116
-- ==============================

0 commit comments

Comments
 (0)