From 4709441f6388733c5b276109d4a09df670aa5829 Mon Sep 17 00:00:00 2001 From: LeeMyeongJin Date: Thu, 19 Feb 2026 22:05:57 +0900 Subject: [PATCH 1/2] =?UTF-8?q?revert:=20=EA=B4=80=EB=A6=AC=EC=9E=90=20?= =?UTF-8?q?=EC=82=AD=EC=A0=9C=20=EA=B6=8C=ED=95=9C=20=EA=B4=80=EB=A0=A8=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD=EC=82=AC=ED=95=AD=20=EC=A0=84=EC=B2=B4=20?= =?UTF-8?q?=EB=A1=A4=EB=B0=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - PublicCourseService: isAdmin 체크, 스크랩 삭제, Record FK null 처리 제거 - RecordRepository: nullifyPublicCourseIn 메서드 제거 - f8b4c26 상태로 원복 --- .../publicCourse/service/PublicCourseService.java | 12 +----------- .../server/record/repository/RecordRepository.java | 6 ------ 2 files changed, 1 insertion(+), 17 deletions(-) diff --git a/src/main/java/org/runnect/server/publicCourse/service/PublicCourseService.java b/src/main/java/org/runnect/server/publicCourse/service/PublicCourseService.java index 9b2d934..2ab5c99 100644 --- a/src/main/java/org/runnect/server/publicCourse/service/PublicCourseService.java +++ b/src/main/java/org/runnect/server/publicCourse/service/PublicCourseService.java @@ -14,7 +14,6 @@ import org.runnect.server.common.module.convert.CoordinatePathConverter; import org.runnect.server.course.entity.Course; import org.runnect.server.course.repository.CourseRepository; -import org.runnect.server.record.repository.RecordRepository; import org.runnect.server.publicCourse.dto.request.CreatePublicCourseRequestDto; import org.runnect.server.publicCourse.dto.request.DeletePublicCoursesRequestDto; import org.runnect.server.publicCourse.dto.response.CreatePublicCourseResponseDto; @@ -54,7 +53,6 @@ public class PublicCourseService { private final UserRepository userRepository; private final ScrapRepository scrapRepository; private final CourseRepository courseRepository; - private final RecordRepository recordRepository; @Value("${runnect.marathon-public-course-id}") @@ -352,10 +350,8 @@ public DeletePublicCoursesResponseDto deletePublicCourses( throw new NotFoundException(ErrorStatus.NOT_FOUND_PUBLICCOURSE_EXCEPTION, ErrorStatus.NOT_FOUND_PUBLICCOURSE_EXCEPTION.getMessage()); } - boolean isAdmin = userId.equals(280L); - publicCourses.stream() - .filter(pc -> !isAdmin && !pc.getCourse().getRunnectUser().equals(user)) + .filter(pc -> !pc.getCourse().getRunnectUser().equals(user)) .findAny() .ifPresent(pc -> { throw new PermissionDeniedException( @@ -363,12 +359,6 @@ public DeletePublicCoursesResponseDto deletePublicCourses( ErrorStatus.PERMISSION_DENIED_PUBLIC_COURSE_DELETE_EXCEPTION.getMessage()); }); - //삭제전 연관된 스크랩 먼저 삭제 - scrapRepository.deleteByPublicCourseIn(publicCourses); - - //삭제전 연관된 Record의 publicCourse FK null 처리 - recordRepository.nullifyPublicCourseIn(publicCourses); - //삭제전 course의 isPrivate update publicCourses.forEach(publicCourse -> publicCourse.getCourse().retrieveCourse()); diff --git a/src/main/java/org/runnect/server/record/repository/RecordRepository.java b/src/main/java/org/runnect/server/record/repository/RecordRepository.java index 5d09675..fe2c80f 100644 --- a/src/main/java/org/runnect/server/record/repository/RecordRepository.java +++ b/src/main/java/org/runnect/server/record/repository/RecordRepository.java @@ -1,10 +1,8 @@ package org.runnect.server.record.repository; import java.util.Collection; -import org.runnect.server.publicCourse.entity.PublicCourse; import org.runnect.server.record.entity.Record; import org.runnect.server.user.entity.RunnectUser; -import org.springframework.data.jpa.repository.Modifying; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.Repository; import org.springframework.data.repository.query.Param; @@ -31,8 +29,4 @@ public interface RecordRepository extends Repository { // DELETE long deleteByIdIn(Collection ids); - - @Modifying - @Query("UPDATE Record r SET r.publicCourse = null WHERE r.publicCourse IN :publicCourses") - int nullifyPublicCourseIn(@Param("publicCourses") Collection publicCourses); } From 24805ddb91c9cc53371f2ceec0085d92ffcd1a48 Mon Sep 17 00:00:00 2001 From: LeeMyeongJin Date: Thu, 19 Feb 2026 22:26:26 +0900 Subject: [PATCH 2/2] =?UTF-8?q?feat:=20=EA=B4=80=EB=A6=AC=EC=9E=90=20?= =?UTF-8?q?=EA=B3=B5=EA=B0=9C=20=EC=BD=94=EC=8A=A4=20=EC=82=AD=EC=A0=9C=20?= =?UTF-8?q?=EA=B6=8C=ED=95=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - userId 280(관리자) 소유권 검증 우회 - EntityManager JPQL로 Record FK null 처리 - Scrap 삭제 후 PublicCourse 삭제 (FK 순서 보장) --- .../service/PublicCourseService.java | 20 ++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/runnect/server/publicCourse/service/PublicCourseService.java b/src/main/java/org/runnect/server/publicCourse/service/PublicCourseService.java index 2ab5c99..1a38091 100644 --- a/src/main/java/org/runnect/server/publicCourse/service/PublicCourseService.java +++ b/src/main/java/org/runnect/server/publicCourse/service/PublicCourseService.java @@ -43,17 +43,24 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import javax.persistence.EntityManager; +import javax.persistence.PersistenceContext; + @Service @RequiredArgsConstructor public class PublicCourseService { private static final Integer PAGE_SIZE = 10; private static List MARATHON_PUBLIC_COURSE_IDS; + private static final Long ADMIN_USER_ID = 280L; private final PublicCourseRepository publicCourseRepository; private final UserRepository userRepository; private final ScrapRepository scrapRepository; private final CourseRepository courseRepository; + @PersistenceContext + private EntityManager entityManager; + @Value("${runnect.marathon-public-course-id}") private void setMARATHON_PUBLIC_COURSE_IDS(String MARATHON_PUBLIC_COURSE_ID) { @@ -350,8 +357,10 @@ public DeletePublicCoursesResponseDto deletePublicCourses( throw new NotFoundException(ErrorStatus.NOT_FOUND_PUBLICCOURSE_EXCEPTION, ErrorStatus.NOT_FOUND_PUBLICCOURSE_EXCEPTION.getMessage()); } + boolean isAdmin = userId.equals(ADMIN_USER_ID); + publicCourses.stream() - .filter(pc -> !pc.getCourse().getRunnectUser().equals(user)) + .filter(pc -> !isAdmin && !pc.getCourse().getRunnectUser().equals(user)) .findAny() .ifPresent(pc -> { throw new PermissionDeniedException( @@ -362,6 +371,15 @@ public DeletePublicCoursesResponseDto deletePublicCourses( //삭제전 course의 isPrivate update publicCourses.forEach(publicCourse -> publicCourse.getCourse().retrieveCourse()); + // Record의 publicCourse FK를 null로 설정 (Record 테이블 FK 제약조건 해제) + entityManager.createQuery( + "UPDATE Record r SET r.publicCourse = null WHERE r.publicCourse IN :publicCourses") + .setParameter("publicCourses", publicCourses) + .executeUpdate(); + + // Scrap 삭제 (Scrap 테이블 FK NOT NULL 제약조건) + scrapRepository.deleteByPublicCourseIn(publicCourses); + publicCourseRepository.deleteAllInBatch(publicCourses); return DeletePublicCoursesResponseDto.from(publicCourses.size());