-
Notifications
You must be signed in to change notification settings - Fork 1
20260404 #623 거래 완료 후 후기 작성 api #634
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
The head ref may contain hidden characters: "20260404_#623_\uAC70\uB798_\uC644\uB8CC_\uD6C4_\uD6C4\uAE30_\uC791\uC131_API"
Changes from all commits
41c62a5
d339df3
7258f0a
9bdaa90
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| package com.romrom.common.constant; | ||
|
|
||
| import lombok.AllArgsConstructor; | ||
| import lombok.Getter; | ||
|
|
||
| @AllArgsConstructor | ||
| @Getter | ||
| public enum TradeReviewRating { | ||
| BAD("별로예요"), | ||
| GOOD("좋아요"), | ||
| GREAT("최고예요"), | ||
| ; | ||
|
|
||
| private final String description; | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,17 @@ | ||
| package com.romrom.common.constant; | ||
|
|
||
| import lombok.AllArgsConstructor; | ||
| import lombok.Getter; | ||
|
|
||
| @AllArgsConstructor | ||
| @Getter | ||
| public enum TradeReviewTag { | ||
| FAST_RESPONSE("답장이 빨라요"), | ||
| GOOD_ITEM_CONDITION("물건 상태가 좋아요"), | ||
| MATCHES_PHOTO("사진과 같아요"), | ||
| PUNCTUAL("약속을 잘 지켜요"), | ||
| KIND("친절해요"), | ||
| ; | ||
|
|
||
| private final String description; | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,48 @@ | ||
| package com.romrom.item.entity.postgres; | ||
|
|
||
| import com.fasterxml.jackson.annotation.JsonIgnoreProperties; | ||
| import com.romrom.common.constant.TradeReviewRating; | ||
| import com.romrom.common.constant.TradeReviewTag; | ||
| import com.romrom.common.entity.postgres.BasePostgresEntity; | ||
| import com.romrom.member.entity.Member; | ||
| import jakarta.persistence.*; | ||
| import lombok.*; | ||
| import lombok.experimental.SuperBuilder; | ||
|
|
||
| import java.util.List; | ||
| import java.util.UUID; | ||
|
|
||
| @Entity | ||
| @Getter | ||
| @Setter | ||
| @SuperBuilder | ||
| @AllArgsConstructor | ||
| @NoArgsConstructor | ||
| @ToString(callSuper = true) | ||
| @JsonIgnoreProperties({"hibernateLazyInitializer", "handler"}) | ||
| public class TradeReview extends BasePostgresEntity { | ||
|
|
||
| @Id | ||
| @GeneratedValue(strategy = GenerationType.UUID) | ||
| @Column(nullable = false, updatable = false) | ||
| private UUID tradeReviewId; | ||
|
|
||
| @ManyToOne(fetch = FetchType.LAZY) | ||
| private TradeRequestHistory tradeRequestHistory; | ||
|
|
||
| @ManyToOne(fetch = FetchType.LAZY) | ||
| private Member reviewerMember; // 후기 작성자 | ||
|
|
||
| @ManyToOne(fetch = FetchType.LAZY) | ||
| private Member reviewedMember; // 후기 받는 사람 | ||
|
nayoung04 marked this conversation as resolved.
|
||
|
|
||
| @Enumerated(EnumType.STRING) | ||
| @Column(nullable = false) | ||
| private TradeReviewRating tradeReviewRating; // 종합 평가 | ||
|
|
||
| @ElementCollection | ||
| private List<TradeReviewTag> tradeReviewTags; // 세부 항목 | ||
|
nayoung04 marked this conversation as resolved.
|
||
|
|
||
| @Column(length = 200) | ||
| private String reviewComment; // 한마디 | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| package com.romrom.item.repository.postgres; | ||
|
|
||
| import com.romrom.item.entity.postgres.TradeRequestHistory; | ||
| import com.romrom.item.entity.postgres.TradeReview; | ||
| import com.romrom.member.entity.Member; | ||
| import java.util.UUID; | ||
| import org.springframework.data.jpa.repository.JpaRepository; | ||
|
|
||
| public interface TradeReviewRepository extends JpaRepository<TradeReview, UUID> { | ||
|
|
||
| // 동일 거래에 같은 작성자의 후기가 이미 존재하는지 확인 | ||
| boolean existsByTradeRequestHistoryAndReviewerMember( | ||
| TradeRequestHistory tradeRequestHistory, Member reviewerMember); | ||
|
nayoung04 marked this conversation as resolved.
|
||
| } | ||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,92 @@ | ||||||||||||||||||||||||||||||
| package com.romrom.item.service; | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| import com.romrom.common.constant.TradeStatus; | ||||||||||||||||||||||||||||||
| import com.romrom.common.exception.CustomException; | ||||||||||||||||||||||||||||||
| import com.romrom.common.exception.ErrorCode; | ||||||||||||||||||||||||||||||
| import com.romrom.item.dto.TradeRequest; | ||||||||||||||||||||||||||||||
| import com.romrom.item.entity.postgres.TradeRequestHistory; | ||||||||||||||||||||||||||||||
| import com.romrom.item.entity.postgres.TradeReview; | ||||||||||||||||||||||||||||||
| import com.romrom.item.repository.postgres.TradeRequestHistoryRepository; | ||||||||||||||||||||||||||||||
| import com.romrom.item.repository.postgres.TradeReviewRepository; | ||||||||||||||||||||||||||||||
| import com.romrom.member.entity.Member; | ||||||||||||||||||||||||||||||
| import lombok.RequiredArgsConstructor; | ||||||||||||||||||||||||||||||
| import lombok.extern.slf4j.Slf4j; | ||||||||||||||||||||||||||||||
| import org.springframework.dao.DataIntegrityViolationException; | ||||||||||||||||||||||||||||||
| import org.springframework.stereotype.Service; | ||||||||||||||||||||||||||||||
| import org.springframework.transaction.annotation.Transactional; | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| import java.util.UUID; | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| @Service | ||||||||||||||||||||||||||||||
| @RequiredArgsConstructor | ||||||||||||||||||||||||||||||
| @Slf4j | ||||||||||||||||||||||||||||||
| public class TradeReviewService { | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| private final TradeReviewRepository tradeReviewRepository; | ||||||||||||||||||||||||||||||
| private final TradeRequestHistoryRepository tradeRequestHistoryRepository; | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| // 후기 작성 | ||||||||||||||||||||||||||||||
| @Transactional | ||||||||||||||||||||||||||||||
| public void postTradeReview(TradeRequest request) { | ||||||||||||||||||||||||||||||
| TradeRequestHistory tradeRequestHistory = findTradeRequestHistoryById(request.getTradeRequestHistoryId()); | ||||||||||||||||||||||||||||||
| Member reviewerMember = request.getMember(); | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| // 종합 평가 필수 검증 | ||||||||||||||||||||||||||||||
| if (request.getTradeReviewRating() == null) { | ||||||||||||||||||||||||||||||
| log.error("종합 평가가 누락되었습니다. memberId={}", reviewerMember.getMemberId()); | ||||||||||||||||||||||||||||||
| throw new CustomException(ErrorCode.INVALID_REQUEST); | ||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||
|
nayoung04 marked this conversation as resolved.
|
||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| // 거래 완료 상태 검증 | ||||||||||||||||||||||||||||||
| if (tradeRequestHistory.getTradeStatus() != TradeStatus.TRADED) { | ||||||||||||||||||||||||||||||
| log.error("거래 완료 상태가 아닙니다. tradeRequestHistoryId={}, status={}", | ||||||||||||||||||||||||||||||
| tradeRequestHistory.getTradeRequestHistoryId(), tradeRequestHistory.getTradeStatus()); | ||||||||||||||||||||||||||||||
| throw new CustomException(ErrorCode.TRADE_NOT_COMPLETED); | ||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| // 후기 작성 권한 검증 (거래 당사자만 작성 가능) | ||||||||||||||||||||||||||||||
| Member takeItemOwner = tradeRequestHistory.getTakeItem().getMember(); | ||||||||||||||||||||||||||||||
| Member giveItemOwner = tradeRequestHistory.getGiveItem().getMember(); | ||||||||||||||||||||||||||||||
| boolean isTradeParticipant = reviewerMember.getMemberId().equals(takeItemOwner.getMemberId()) | ||||||||||||||||||||||||||||||
| || reviewerMember.getMemberId().equals(giveItemOwner.getMemberId()); | ||||||||||||||||||||||||||||||
| if (!isTradeParticipant) { | ||||||||||||||||||||||||||||||
| log.error("거래 당사자가 아닙니다. memberId={}, tradeRequestHistoryId={}", | ||||||||||||||||||||||||||||||
| reviewerMember.getMemberId(), tradeRequestHistory.getTradeRequestHistoryId()); | ||||||||||||||||||||||||||||||
| throw new CustomException(ErrorCode.TRADE_REVIEW_ACCESS_FORBIDDEN); | ||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| // 중복 후기 검증 | ||||||||||||||||||||||||||||||
| if (tradeReviewRepository.existsByTradeRequestHistoryAndReviewerMember(tradeRequestHistory, reviewerMember)) { | ||||||||||||||||||||||||||||||
| log.error("이미 후기를 작성했습니다. memberId={}, tradeRequestHistoryId={}", | ||||||||||||||||||||||||||||||
| reviewerMember.getMemberId(), tradeRequestHistory.getTradeRequestHistoryId()); | ||||||||||||||||||||||||||||||
| throw new CustomException(ErrorCode.TRADE_REVIEW_ALREADY_EXISTS); | ||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| // 후기 받는 사람 결정 (작성자의 반대편 거래 참여자) | ||||||||||||||||||||||||||||||
| Member reviewedMember = reviewerMember.getMemberId().equals(takeItemOwner.getMemberId()) | ||||||||||||||||||||||||||||||
| ? giveItemOwner | ||||||||||||||||||||||||||||||
| : takeItemOwner; | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| TradeReview tradeReview = TradeReview.builder() | ||||||||||||||||||||||||||||||
| .tradeRequestHistory(tradeRequestHistory) | ||||||||||||||||||||||||||||||
| .reviewerMember(reviewerMember) | ||||||||||||||||||||||||||||||
| .reviewedMember(reviewedMember) | ||||||||||||||||||||||||||||||
| .tradeReviewRating(request.getTradeReviewRating()) | ||||||||||||||||||||||||||||||
| .tradeReviewTags(request.getTradeReviewTags()) | ||||||||||||||||||||||||||||||
| .reviewComment(request.getReviewComment()) | ||||||||||||||||||||||||||||||
| .build(); | ||||||||||||||||||||||||||||||
| try { | ||||||||||||||||||||||||||||||
| tradeReviewRepository.save(tradeReview); | ||||||||||||||||||||||||||||||
| } catch (DataIntegrityViolationException e) { | ||||||||||||||||||||||||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. DataIntegrityViolationException 에 대해서만 핸들링하나요? |
||||||||||||||||||||||||||||||
| log.warn("중복 후기 저장 시도 (DB 유니크 제약 위반): tradeRequestHistoryId={}, memberId={}", | ||||||||||||||||||||||||||||||
| tradeRequestHistory.getTradeRequestHistoryId(), reviewerMember.getMemberId()); | ||||||||||||||||||||||||||||||
| throw new CustomException(ErrorCode.TRADE_REVIEW_ALREADY_EXISTS); | ||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||
|
Comment on lines
+80
to
+84
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🏁 Script executed: #!/bin/bash
set -euo pipefail
echo "[1] TradeReview 제약/필드 확인"
fd -i 'TradeReview.java' --exec sed -n '1,220p' {}
echo
echo "[2] 후기 코멘트 길이 및 요청 검증 로직 탐색"
rg -n --type=java -C2 'reviewComment|@Size|length = 200|tradeReviewRating|INVALID_REQUEST'
echo
echo "[3] DataIntegrityViolationException 처리 지점 및 매핑 코드 확인"
rg -n --type=java -C3 'DataIntegrityViolationException|TRADE_REVIEW_ALREADY_EXISTS'Repository: TEAM-ROMROM/RomRom-BE Length of output: 26659 🏁 Script executed: #!/bin/bash
set -euo pipefail
echo "[1] Full TradeRequest.java definition"
fd -i 'TradeRequest.java' -path '*/item/dto/*' --exec cat {} \;
echo
echo "[2] Search for `@Size/`@Length/@Valid/@Validated annotations on reviewComment"
rg -n --type=java '@Size|@Length|@Validated' -B2 -A2 'reviewComment'
echo
echo "[3] Controller layer - validate if request body validation is enabled"
rg -n --type=java '@Valid|@RequestBody' --glob='*TradeController.java' -C3 'createTradeReview'
echo
echo "[4] Check for any database migration or constraint definition files"
fd -i 'migration|schema|constraint|flyway' -type f | head -20
echo
echo "[5] Verify if there are `@NotNull/`@NotBlank on other TradeReview fields"
rg -n --type=java -B5 'class TradeReview' | head -50Repository: TEAM-ROMROM/RomRom-BE Length of output: 288 🏁 Script executed: #!/bin/bash
set -euo pipefail
echo "[1] Full TradeRequest.java definition"
fd 'TradeRequest.java' -path '*/item/dto/*' --exec cat {} \;
echo
echo "[2] Search for `@Size/`@Length/@Valid/@Validated annotations in DTO"
rg -n --type=java '@Size|@Length|@Valid|@NotNull|@NotBlank' RomRom-Domain-Item/src/main/java/com/romrom/item/dto/
echo
echo "[3] Controller layer validation on createTradeReview endpoint"
rg -n --type=java -A10 'createTradeReview' | grep -A10 '@Valid\|@RequestBody'
echo
echo "[4] Check TradeReview entity for all column constraints"
fd 'TradeReview.java' -path '*/entity/postgres/*' --exec cat {} \;
echo
echo "[5] Search for unique constraint definitions in entity or schema"
rg -n --type=java '@Unique|uniqueConstraints|@Column.*unique' RomRom-Domain-Item/Repository: TEAM-ROMROM/RomRom-BE Length of output: 288 🏁 Script executed: #!/bin/bash
set -euo pipefail
echo "[1] Full TradeRequest.java definition"
find . -name "TradeRequest.java" -path "*/dto/*" -exec cat {} \;
echo
echo "[2] Search for validation annotations in item/dto directory"
rg '@Size|@Length|@Valid|@NotNull|@NotBlank' RomRom-Domain-Item/src/main/java/com/romrom/item/dto/ || true
echo
echo "[3] Full TradeReview entity definition"
find . -name "TradeReview.java" -path "*/entity/postgres/*" -exec cat {} \;
echo
echo "[4] Search for unique constraints in TradeReview"
rg -C5 'TradeReview|@Unique' RomRom-Domain-Item/src/main/java/com/romrom/item/entity/ || true
echo
echo "[5] Search for `@Valid` on createTradeReview controller endpoint"
rg -B5 -A15 'createTradeReview' RomRom-Web/src/main/java/com/romrom/web/controller/ || trueRepository: TEAM-ROMROM/RomRom-BE Length of output: 7430 🏁 Script executed: #!/bin/bash
set -euo pipefail
echo "[1] Search for Flyway/Liquibase migration files with TradeReview constraints"
find . -type f \( -name "*.sql" -o -name "*.yaml" -o -name "*.xml" \) | xargs grep -l "trade_review\|TradeReview" 2>/dev/null || echo "No migration files found with TradeReview"
echo
echo "[2] Search for `@Table` annotation with unique constraints on TradeReview"
rg '@Table' RomRom-Domain-Item/src/main/java/com/romrom/item/entity/ -A5
echo
echo "[3] Check BasePostgresEntity for any constraint definitions"
find . -name "BasePostgresEntity.java" -exec cat {} \;
echo
echo "[4] Search for TradeController createTradeReview method signature with `@Valid`"
find . -name "*TradeController.java" ! -path "*/Docs.java" -exec grep -A10 "createTradeReview" {} \;
echo
echo "[5] Look for database initialization or schema definition files in resources"
find . -path "*/resources/*" -name "*.sql" -o -name "*.yaml" | head -20Repository: TEAM-ROMROM/RomRom-BE Length of output: 301 🏁 Script executed: #!/bin/bash
set -euo pipefail
echo "[1] Read TradeReview migration file"
cat ./RomRom-Web/src/main/resources/db/migration/V1_4_58__add_trade_review_constraints.sql
echo
echo "[2] Search for all migration files related to TradeReview in order"
find . -path "*/db/migration/*" -name "*trade_review*" -o -path "*/db/migration/*" -name "*TradeReview*" | sort
echo
echo "[3] Read TradeReviewService createTradeReview method fully"
sed -n '28,90p' RomRom-Domain-Item/src/main/java/com/romrom/item/service/TradeReviewService.javaRepository: TEAM-ROMROM/RomRom-BE Length of output: 6439 🏁 Script executed: #!/bin/bash
set -euo pipefail
echo "[1] Verify if reviewComment validation is in controller or interceptor"
find . -name "*TradeController.java" ! -path "*/Docs.java" -exec cat {} \;Repository: TEAM-ROMROM/RomRom-BE Length of output: 6363 DataIntegrityViolationException 전체를 중복후기로 매핑하면 오진됩니다. Lines 80-84에서 모든 DataIntegrityViolationException을 TRADE_REVIEW_ALREADY_EXISTS로 변환하고 있습니다. 데이터베이스 마이그레이션(V1_4_58__add_trade_review_constraints.sql)에 따르면 trade_review 테이블에는 (trade_request_history_id, reviewer_member_id) 복합 유니크 제약 외에도 3개의 NOT NULL 제약이 있습니다. 또한 TradeRequest.reviewComment에는 라인 59에서 existsByTradeRequestHistoryAndReviewerMember로 사전 검증하고 있으므로, catch 블록은 동시성 환경의 안전장치 역할입니다. 하지만 특정 유니크 제약 위반만 TRADE_REVIEW_ALREADY_EXISTS로 매핑하고, 나머지 무결성 제약 위반은 INVALID_REQUEST나 다른 적절한 에러코드로 처리해야 합니다. 수정 방향 예시 try {
tradeReviewRepository.save(tradeReview);
} catch (DataIntegrityViolationException e) {
- log.warn("중복 후기 저장 시도 (DB 유니크 제약 위반): tradeRequestHistoryId={}, memberId={}",
- tradeRequestHistory.getTradeRequestHistoryId(), reviewerMember.getMemberId());
- throw new CustomException(ErrorCode.TRADE_REVIEW_ALREADY_EXISTS);
+ String message = e.getMostSpecificCause() != null ? e.getMostSpecificCause().getMessage() : "";
+ if (message != null && message.contains("uk_trade_review_history_reviewer")) {
+ log.warn("중복 후기 저장 시도 (DB 유니크 제약 위반): tradeRequestHistoryId={}, memberId={}",
+ tradeRequestHistory.getTradeRequestHistoryId(), reviewerMember.getMemberId());
+ throw new CustomException(ErrorCode.TRADE_REVIEW_ALREADY_EXISTS);
+ }
+ throw new CustomException(ErrorCode.INVALID_REQUEST);
}📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||
| log.debug("후기 작성 완료: tradeReviewId={}", tradeReview.getTradeReviewId()); | ||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| private TradeRequestHistory findTradeRequestHistoryById(UUID tradeRequestHistoryId) { | ||||||||||||||||||||||||||||||
| return tradeRequestHistoryRepository.findByTradeRequestHistoryIdWithItems(tradeRequestHistoryId) | ||||||||||||||||||||||||||||||
| .orElseThrow(() -> new CustomException(ErrorCode.TRADE_REQUEST_NOT_FOUND)); | ||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,76 @@ | ||
| -- trade_review 테이블 무결성 제약 추가 | ||
| -- tradeRequestHistory → trade_request_history_trade_request_history_id | ||
| -- reviewerMember → reviewer_member_member_id | ||
| -- reviewedMember → reviewed_member_member_id | ||
| -- 1. FK 컬럼 NOT NULL 제약 | ||
| -- 2. (trade_request_history_trade_request_history_id, reviewer_member_member_id) 복합 유니크 제약 → 동시성 환경에서 중복 후기 방지 | ||
| DO $$ | ||
| BEGIN | ||
| IF EXISTS ( | ||
| SELECT 1 FROM information_schema.tables | ||
| WHERE table_schema = 'public' | ||
| AND table_name = 'trade_review' | ||
| ) THEN | ||
|
|
||
| -- trade_request_history_trade_request_history_id NOT NULL | ||
| IF EXISTS ( | ||
| SELECT 1 FROM information_schema.columns | ||
| WHERE table_schema = 'public' | ||
| AND table_name = 'trade_review' | ||
| AND column_name = 'trade_request_history_trade_request_history_id' | ||
| AND is_nullable = 'YES' | ||
| ) THEN | ||
| ALTER TABLE public.trade_review | ||
| ALTER COLUMN trade_request_history_trade_request_history_id SET NOT NULL; | ||
| RAISE NOTICE 'trade_request_history_trade_request_history_id NOT NULL 제약을 추가했습니다'; | ||
| END IF; | ||
|
|
||
| -- reviewer_member_member_id NOT NULL | ||
| IF EXISTS ( | ||
| SELECT 1 FROM information_schema.columns | ||
| WHERE table_schema = 'public' | ||
| AND table_name = 'trade_review' | ||
| AND column_name = 'reviewer_member_member_id' | ||
| AND is_nullable = 'YES' | ||
| ) THEN | ||
| ALTER TABLE public.trade_review | ||
| ALTER COLUMN reviewer_member_member_id SET NOT NULL; | ||
| RAISE NOTICE 'reviewer_member_member_id NOT NULL 제약을 추가했습니다'; | ||
| END IF; | ||
|
|
||
| -- reviewed_member_member_id NOT NULL | ||
| IF EXISTS ( | ||
| SELECT 1 FROM information_schema.columns | ||
| WHERE table_schema = 'public' | ||
| AND table_name = 'trade_review' | ||
| AND column_name = 'reviewed_member_member_id' | ||
| AND is_nullable = 'YES' | ||
| ) THEN | ||
| ALTER TABLE public.trade_review | ||
| ALTER COLUMN reviewed_member_member_id SET NOT NULL; | ||
| RAISE NOTICE 'reviewed_member_member_id NOT NULL 제약을 추가했습니다'; | ||
| END IF; | ||
|
|
||
| -- (trade_request_history_trade_request_history_id, reviewer_member_member_id) 복합 유니크 제약 | ||
| IF NOT EXISTS ( | ||
| SELECT 1 FROM information_schema.table_constraints | ||
| WHERE table_schema = 'public' | ||
| AND constraint_name = 'uk_trade_review_history_reviewer' | ||
| AND table_name = 'trade_review' | ||
| ) THEN | ||
| ALTER TABLE public.trade_review | ||
| ADD CONSTRAINT uk_trade_review_history_reviewer | ||
| UNIQUE (trade_request_history_trade_request_history_id, reviewer_member_member_id); | ||
| RAISE NOTICE 'uk_trade_review_history_reviewer 유니크 제약을 추가했습니다'; | ||
| ELSE | ||
| RAISE NOTICE 'uk_trade_review_history_reviewer 이미 존재합니다. 스킵합니다'; | ||
| END IF; | ||
|
|
||
| ELSE | ||
| RAISE NOTICE 'trade_review 테이블이 존재하지 않습니다. JPA가 생성할 예정입니다'; | ||
| END IF; | ||
|
|
||
| EXCEPTION | ||
| WHEN OTHERS THEN | ||
| RAISE WARNING '마이그레이션 중 오류 발생: %', SQLERRM; | ||
| END $$; |
Uh oh!
There was an error while loading. Please reload this page.