From ac5423ef3e33b8baed978338e4dc2cafc700a1c8 Mon Sep 17 00:00:00 2001 From: teddy Date: Fri, 9 Jan 2026 11:21:43 +0900 Subject: [PATCH] =?UTF-8?q?[KC-99]=20=EC=B6=94=EB=A1=A0=EA=B4=80=EB=A6=AC?= =?UTF-8?q?=20=EB=93=B1=EB=A1=9D=20dto=20=EC=88=98=EC=A0=95,=20spoless=20?= =?UTF-8?q?=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../inference/dto/InferenceResultDto.java | 19 +++---- .../label/LabelAllocateApiController.java | 19 ++++--- .../core/InferenceResultCoreService.java | 47 +++++++++++++++-- .../core/LabelAllocateCoreService.java | 1 - .../entity/MapSheetLearn5kEntity.java | 51 +++++++++++++++++++ .../postgres/entity/MapSheetLearnEntity.java | 4 +- .../Inference/MapSheetLearn5kRepository.java | 7 +++ .../MapSheetLearn5kRepositoryCustom.java | 3 ++ .../MapSheetLearn5kRepositoryImpl.java | 6 +++ .../label/LabelAllocateRepositoryCustom.java | 1 - .../label/LabelAllocateRepositoryImpl.java | 1 - src/main/resources/application-dev.yml | 3 ++ src/main/resources/application-prod.yml | 6 ++- 13 files changed, 140 insertions(+), 28 deletions(-) create mode 100644 src/main/java/com/kamco/cd/kamcoback/postgres/entity/MapSheetLearn5kEntity.java create mode 100644 src/main/java/com/kamco/cd/kamcoback/postgres/repository/Inference/MapSheetLearn5kRepository.java create mode 100644 src/main/java/com/kamco/cd/kamcoback/postgres/repository/Inference/MapSheetLearn5kRepositoryCustom.java create mode 100644 src/main/java/com/kamco/cd/kamcoback/postgres/repository/Inference/MapSheetLearn5kRepositoryImpl.java diff --git a/src/main/java/com/kamco/cd/kamcoback/inference/dto/InferenceResultDto.java b/src/main/java/com/kamco/cd/kamcoback/inference/dto/InferenceResultDto.java index 26efc23d..c9d5cabf 100644 --- a/src/main/java/com/kamco/cd/kamcoback/inference/dto/InferenceResultDto.java +++ b/src/main/java/com/kamco/cd/kamcoback/inference/dto/InferenceResultDto.java @@ -64,9 +64,10 @@ public class InferenceResultDto { @Getter @AllArgsConstructor public enum MapSheetScope implements EnumType { - EXCL("추론제외"), - PREV("이전 년도 도엽 사용"), + ALL("전체"), + PART("부분"), ; + private final String desc; @Override @@ -84,8 +85,8 @@ public class InferenceResultDto { @Getter @AllArgsConstructor public enum DetectOption implements EnumType { - ALL("전체"), - PART("부분"), + EXCL("추론제외"), + PREV("이전 년도 도엽 사용"), ; private final String desc; @@ -131,16 +132,16 @@ public class InferenceResultDto { @NotNull private Integer targetYyyy; + @Schema(description = "분석대상 도엽 - 전체(ALL), 부분(PART)", example = "PART") + @NotBlank + @EnumValid(enumClass = DetectOption.class, message = "분석대상 도엽 옵션은 '전체', '부분' 만 사용 가능합니다.") + private String mapSheetScope; + @Schema(description = "탐지 데이터 옵션 - 추론제외(PREV), 이전 년도 도엽 사용(PREV)", example = "EXCL") @NotBlank @EnumValid( enumClass = MapSheetScope.class, message = "탐지 데이터 옵션은 '추론제외', '이전 년도 도엽 사용' 만 사용 가능합니다.") - private String mapSheetScope; - - @Schema(description = "분석대상 도엽 - 전체(ALL), 부분(PART)", example = "PART") - @NotBlank - @EnumValid(enumClass = DetectOption.class, message = "분석대상 도엽 옵션은 '전체', '부분' 만 사용 가능합니다.") private String detectOption; @Schema(description = "5k 도협 번호 목록", example = "[34607067,34607067]") diff --git a/src/main/java/com/kamco/cd/kamcoback/label/LabelAllocateApiController.java b/src/main/java/com/kamco/cd/kamcoback/label/LabelAllocateApiController.java index f6da8a1d..31bd064e 100644 --- a/src/main/java/com/kamco/cd/kamcoback/label/LabelAllocateApiController.java +++ b/src/main/java/com/kamco/cd/kamcoback/label/LabelAllocateApiController.java @@ -76,9 +76,7 @@ public class LabelAllocateApiController { schema = @Schema(allowableValues = {"LABELER", "REVIEWER"})) @RequestParam(required = false) String type, - @Parameter( - description = "검색어 (작업자 이름 또는 사번으로 검색, 부분 일치) - 미입력 시 전체 조회", - example = "김라벨") + @Parameter(description = "검색어 (작업자 이름 또는 사번으로 검색, 부분 일치) - 미입력 시 전체 조회", example = "김라벨") @RequestParam(required = false) String search, @Parameter( @@ -259,27 +257,32 @@ public class LabelAllocateApiController { examples = { @io.swagger.v3.oas.annotations.media.ExampleObject( name = "라벨링 종료", - value = """ + value = + """ {"closedType": "LABELING", "closedYn": "Y"} """), @io.swagger.v3.oas.annotations.media.ExampleObject( name = "검수 종료", - value = """ + value = + """ {"closedType": "INSPECTION", "closedYn": "Y"} """), @io.swagger.v3.oas.annotations.media.ExampleObject( name = "라벨링 재개", - value = """ + value = + """ {"closedType": "LABELING", "closedYn": "N"} """), @io.swagger.v3.oas.annotations.media.ExampleObject( name = "검수 재개", - value = """ + value = + """ {"closedType": "INSPECTION", "closedYn": "N"} """), @io.swagger.v3.oas.annotations.media.ExampleObject( name = "특정 프로젝트 라벨링 종료", - value = """ + value = + """ {"uuid": "f97dc186-e6d3-4645-9737-3173dde8dc64", "closedType": "LABELING", "closedYn": "Y"} """) })) diff --git a/src/main/java/com/kamco/cd/kamcoback/postgres/core/InferenceResultCoreService.java b/src/main/java/com/kamco/cd/kamcoback/postgres/core/InferenceResultCoreService.java index 34fe6e51..b3f32167 100644 --- a/src/main/java/com/kamco/cd/kamcoback/postgres/core/InferenceResultCoreService.java +++ b/src/main/java/com/kamco/cd/kamcoback/postgres/core/InferenceResultCoreService.java @@ -1,6 +1,6 @@ package com.kamco.cd.kamcoback.postgres.core; -import com.fasterxml.jackson.databind.ObjectMapper; +import com.kamco.cd.kamcoback.common.utils.UserUtil; import com.kamco.cd.kamcoback.inference.dto.InferenceDetailDto; import com.kamco.cd.kamcoback.inference.dto.InferenceDetailDto.Dashboard; import com.kamco.cd.kamcoback.inference.dto.InferenceDetailDto.MapSheet; @@ -9,15 +9,18 @@ import com.kamco.cd.kamcoback.inference.dto.InferenceResultDto.ResultList; import com.kamco.cd.kamcoback.postgres.entity.MapInkx5kEntity; import com.kamco.cd.kamcoback.postgres.entity.MapSheetAnalDataInferenceEntity; import com.kamco.cd.kamcoback.postgres.entity.MapSheetAnalDataInferenceGeomEntity; +import com.kamco.cd.kamcoback.postgres.entity.MapSheetLearn5kEntity; import com.kamco.cd.kamcoback.postgres.entity.MapSheetLearnEntity; import com.kamco.cd.kamcoback.postgres.repository.Inference.MapSheetAnalDataInferenceRepository; +import com.kamco.cd.kamcoback.postgres.repository.Inference.MapSheetLearn5kRepository; import com.kamco.cd.kamcoback.postgres.repository.Inference.MapSheetLearnRepository; import com.kamco.cd.kamcoback.postgres.repository.scene.MapInkx5kRepository; +import jakarta.persistence.EntityManager; import jakarta.persistence.EntityNotFoundException; import jakarta.validation.constraints.NotNull; +import java.util.ArrayList; import java.util.List; import lombok.RequiredArgsConstructor; -import org.locationtech.jts.io.geojson.GeoJsonWriter; import org.springframework.data.domain.Page; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -29,9 +32,10 @@ public class InferenceResultCoreService { private final MapSheetAnalDataInferenceRepository mapSheetAnalDataRepository; private final MapSheetLearnRepository mapSheetLearnRepository; private final MapInkx5kRepository mapInkx5kRepository; + private final MapSheetLearn5kRepository mapSheetLearn5kRepository; - private final ObjectMapper objectMapper = new ObjectMapper(); - private final GeoJsonWriter geoJsonWriter = new GeoJsonWriter(); + private final EntityManager entityManager; + private final UserUtil userUtil; /** * 추론관리 목록 @@ -55,7 +59,40 @@ public class InferenceResultCoreService { mapSheetLearnEntity.setM1ModelUid(req.getModel1Uid()); mapSheetLearnEntity.setM2ModelUid(req.getModel2Uid()); mapSheetLearnEntity.setM3ModelUid(req.getModel3Uid()); - // mapSheetLearnRepository.save() + mapSheetLearnEntity.setCompareYyyy(req.getCompareYyyy()); + mapSheetLearnEntity.setTargetYyyy(req.getTargetYyyy()); + mapSheetLearnEntity.setMapSheetScope(req.getMapSheetScope()); + mapSheetLearnEntity.setDetectOption(req.getDetectOption()); + mapSheetLearnEntity.setCreatedUid(userUtil.getId()); + + // learn 테이블 저장 + MapSheetLearnEntity savedLearn = mapSheetLearnRepository.save(mapSheetLearnEntity); + + final int CHUNK = 1000; + List buffer = new ArrayList<>(CHUNK); + List mapSheetNumList = req.getMapSheetNum(); + + // learn 도엽 저장 + for (String mapSheetNum : mapSheetNumList) { + MapSheetLearn5kEntity e = new MapSheetLearn5kEntity(); + e.setLearn(savedLearn); + e.setMapSheetNum(Long.parseLong(mapSheetNum)); + e.setCreatedUid(userUtil.getId()); + buffer.add(e); + + if (buffer.size() == CHUNK) { + mapSheetLearn5kRepository.saveAll(buffer); + mapSheetLearn5kRepository.flush(); + entityManager.clear(); + buffer.clear(); + } + } + + if (!buffer.isEmpty()) { + mapSheetLearn5kRepository.saveAll(buffer); + mapSheetLearn5kRepository.flush(); + entityManager.clear(); + } } /****/ diff --git a/src/main/java/com/kamco/cd/kamcoback/postgres/core/LabelAllocateCoreService.java b/src/main/java/com/kamco/cd/kamcoback/postgres/core/LabelAllocateCoreService.java index 65b2c78c..86c165e9 100644 --- a/src/main/java/com/kamco/cd/kamcoback/postgres/core/LabelAllocateCoreService.java +++ b/src/main/java/com/kamco/cd/kamcoback/postgres/core/LabelAllocateCoreService.java @@ -142,7 +142,6 @@ public class LabelAllocateCoreService { labelAllocateRepository.assignOwnerReAllocate(uuid, userId, paramUserId, assignCount); } - public void updateClosedYnByUuid(String uuid, String closedType, String closedYn) { labelAllocateRepository.updateClosedYnByUuid(uuid, closedType, closedYn); } diff --git a/src/main/java/com/kamco/cd/kamcoback/postgres/entity/MapSheetLearn5kEntity.java b/src/main/java/com/kamco/cd/kamcoback/postgres/entity/MapSheetLearn5kEntity.java new file mode 100644 index 00000000..8c44ef8a --- /dev/null +++ b/src/main/java/com/kamco/cd/kamcoback/postgres/entity/MapSheetLearn5kEntity.java @@ -0,0 +1,51 @@ +package com.kamco.cd.kamcoback.postgres.entity; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.FetchType; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.ManyToOne; +import jakarta.persistence.SequenceGenerator; +import jakarta.persistence.Table; +import jakarta.validation.constraints.NotNull; +import java.time.ZonedDateTime; +import lombok.Getter; +import lombok.Setter; +import org.hibernate.annotations.OnDelete; +import org.hibernate.annotations.OnDeleteAction; + +@Getter +@Setter +@Entity +@Table(name = "tb_map_sheet_learn_5k") +public class MapSheetLearn5kEntity { + + @Id + @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "tb_map_sheet_learn_5k_id_gen") + @SequenceGenerator( + name = "tb_map_sheet_learn_5k_id_gen", + sequenceName = "tb_map_sheet_learn_5k_seq", + allocationSize = 1) + @Column(name = "id", nullable = false) + private Long id; + + @NotNull + @ManyToOne(fetch = FetchType.LAZY, optional = false) + @OnDelete(action = OnDeleteAction.CASCADE) + @JoinColumn(name = "learn_id", nullable = false, referencedColumnName = "id") + private MapSheetLearnEntity learn; + + @NotNull + @Column(name = "map_sheet_num", nullable = false) + private Long mapSheetNum; + + @org.hibernate.annotations.CreationTimestamp + @Column(name = "created_dttm") + private ZonedDateTime createdDttm; + + @Column(name = "created_uid") + private Long createdUid; +} diff --git a/src/main/java/com/kamco/cd/kamcoback/postgres/entity/MapSheetLearnEntity.java b/src/main/java/com/kamco/cd/kamcoback/postgres/entity/MapSheetLearnEntity.java index 062c7d87..5399a611 100644 --- a/src/main/java/com/kamco/cd/kamcoback/postgres/entity/MapSheetLearnEntity.java +++ b/src/main/java/com/kamco/cd/kamcoback/postgres/entity/MapSheetLearnEntity.java @@ -33,7 +33,7 @@ public class MapSheetLearnEntity { @ColumnDefault("gen_random_uuid()") @Column(name = "uuid") - private UUID uuid; + private UUID uuid = UUID.randomUUID(); @Size(max = 200) @NotNull @@ -89,7 +89,7 @@ public class MapSheetLearnEntity { @Column(name = "apply_dttm") private ZonedDateTime applyDttm; - @ColumnDefault("now()") + @org.hibernate.annotations.CreationTimestamp @Column(name = "created_dttm") private ZonedDateTime createdDttm; diff --git a/src/main/java/com/kamco/cd/kamcoback/postgres/repository/Inference/MapSheetLearn5kRepository.java b/src/main/java/com/kamco/cd/kamcoback/postgres/repository/Inference/MapSheetLearn5kRepository.java new file mode 100644 index 00000000..a5969a4a --- /dev/null +++ b/src/main/java/com/kamco/cd/kamcoback/postgres/repository/Inference/MapSheetLearn5kRepository.java @@ -0,0 +1,7 @@ +package com.kamco.cd.kamcoback.postgres.repository.Inference; + +import com.kamco.cd.kamcoback.postgres.entity.MapSheetLearn5kEntity; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface MapSheetLearn5kRepository + extends JpaRepository, MapSheetLearn5kRepositoryCustom {} diff --git a/src/main/java/com/kamco/cd/kamcoback/postgres/repository/Inference/MapSheetLearn5kRepositoryCustom.java b/src/main/java/com/kamco/cd/kamcoback/postgres/repository/Inference/MapSheetLearn5kRepositoryCustom.java new file mode 100644 index 00000000..a81faeae --- /dev/null +++ b/src/main/java/com/kamco/cd/kamcoback/postgres/repository/Inference/MapSheetLearn5kRepositoryCustom.java @@ -0,0 +1,3 @@ +package com.kamco.cd.kamcoback.postgres.repository.Inference; + +public interface MapSheetLearn5kRepositoryCustom {} diff --git a/src/main/java/com/kamco/cd/kamcoback/postgres/repository/Inference/MapSheetLearn5kRepositoryImpl.java b/src/main/java/com/kamco/cd/kamcoback/postgres/repository/Inference/MapSheetLearn5kRepositoryImpl.java new file mode 100644 index 00000000..68c7593c --- /dev/null +++ b/src/main/java/com/kamco/cd/kamcoback/postgres/repository/Inference/MapSheetLearn5kRepositoryImpl.java @@ -0,0 +1,6 @@ +package com.kamco.cd.kamcoback.postgres.repository.Inference; + +import org.springframework.stereotype.Repository; + +@Repository +public class MapSheetLearn5kRepositoryImpl implements MapSheetLearn5kRepositoryCustom {} diff --git a/src/main/java/com/kamco/cd/kamcoback/postgres/repository/label/LabelAllocateRepositoryCustom.java b/src/main/java/com/kamco/cd/kamcoback/postgres/repository/label/LabelAllocateRepositoryCustom.java index 9a7bcc8c..5980da85 100644 --- a/src/main/java/com/kamco/cd/kamcoback/postgres/repository/label/LabelAllocateRepositoryCustom.java +++ b/src/main/java/com/kamco/cd/kamcoback/postgres/repository/label/LabelAllocateRepositoryCustom.java @@ -84,7 +84,6 @@ public interface LabelAllocateRepositoryCustom { void assignOwnerReAllocate(String uuid, String userId, String paramUserId, Long assignCount); - // 프로젝트 종료 여부 업데이트 (uuid 기반) void updateClosedYnByUuid(String uuid, String closedType, String closedYn); } diff --git a/src/main/java/com/kamco/cd/kamcoback/postgres/repository/label/LabelAllocateRepositoryImpl.java b/src/main/java/com/kamco/cd/kamcoback/postgres/repository/label/LabelAllocateRepositoryImpl.java index 12c5450b..95a5105a 100644 --- a/src/main/java/com/kamco/cd/kamcoback/postgres/repository/label/LabelAllocateRepositoryImpl.java +++ b/src/main/java/com/kamco/cd/kamcoback/postgres/repository/label/LabelAllocateRepositoryImpl.java @@ -1433,7 +1433,6 @@ public class LabelAllocateRepositoryImpl implements LabelAllocateRepositoryCusto .execute(); } - @Override public void updateClosedYnByUuid(String uuid, String closedType, String closedYn) { var updateQuery = queryFactory.update(mapSheetAnalInferenceEntity); diff --git a/src/main/resources/application-dev.yml b/src/main/resources/application-dev.yml index 579b7a42..790a1c95 100644 --- a/src/main/resources/application-dev.yml +++ b/src/main/resources/application-dev.yml @@ -11,8 +11,11 @@ spring: hibernate: default_batch_fetch_size: 100 # ✅ 성능 - N+1 쿼리 방지 order_updates: true # ✅ 성능 - 업데이트 순서 정렬로 데드락 방지 + order_inserts: true use_sql_comments: true # ⚠️ 선택 - SQL에 주석 추가 (디버깅용) format_sql: true # ⚠️ 선택 - SQL 포맷팅 (가독성) + jdbc: + batch_size: 1000 # ✅ 추가 (JDBC batch) datasource: url: jdbc:postgresql://192.168.2.127:15432/kamco_cds diff --git a/src/main/resources/application-prod.yml b/src/main/resources/application-prod.yml index 7c633ecd..5a23ca0e 100644 --- a/src/main/resources/application-prod.yml +++ b/src/main/resources/application-prod.yml @@ -4,14 +4,18 @@ spring: on-profile: prod jpa: - show-sql: false + show-sql: true hibernate: ddl-auto: validate properties: hibernate: default_batch_fetch_size: 100 # ✅ 성능 - N+1 쿼리 방지 order_updates: true # ✅ 성능 - 업데이트 순서 정렬로 데드락 방지 + order_inserts: true use_sql_comments: true # ⚠️ 선택 - SQL에 주석 추가 (디버깅용) + format_sql: true # ⚠️ 선택 - SQL 포맷팅 (가독성) + jdbc: + batch_size: 1000 # ✅ 추가 (JDBC batch) datasource: url: jdbc:postgresql://10.100.0.10:25432/temp