From 85f32d2a2c1abe824caffb243e603358f587e223 Mon Sep 17 00:00:00 2001 From: Rinjae Date: Fri, 19 Dec 2025 14:14:51 +0900 Subject: [PATCH] =?UTF-8?q?GwMetric=20ibatis=20->=20jpa=20=EB=A1=9C=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../obp/repository/ObpGwMetricRepository.java | 25 ++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/eactive/apim/portal/obp/repository/ObpGwMetricRepository.java b/src/main/java/com/eactive/apim/portal/obp/repository/ObpGwMetricRepository.java index ba58e8b..235f372 100644 --- a/src/main/java/com/eactive/apim/portal/obp/repository/ObpGwMetricRepository.java +++ b/src/main/java/com/eactive/apim/portal/obp/repository/ObpGwMetricRepository.java @@ -3,6 +3,8 @@ package com.eactive.apim.portal.obp.repository; import com.eactive.apim.portal.obp.entity.ObpGwMetric; import com.eactive.eai.data.jpa.BaseRepository; import com.eactive.eai.rms.data.EMSDataSource; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; import java.time.LocalDateTime; import java.util.List; @@ -16,9 +18,30 @@ import java.util.Optional; public interface ObpGwMetricRepository extends BaseRepository { /** - * UPSERT 판단을 위한 기존 데이터 조회 + * UPSERT 판단을 위한 기존 데이터 조회 (NULL 안전) * Unique Key: (timeslice, api_id, client_id, hostname, org_id) + * + *

Spring Data JPA의 메서드 이름 기반 쿼리는 NULL 비교를 제대로 처리하지 못함. + * SQL에서 {@code column = NULL}은 항상 false이므로, NULL 값이 있는 레코드를 찾지 못함. + * 이 쿼리는 {@code (column = :param OR (column IS NULL AND :param IS NULL))} 패턴으로 NULL을 안전하게 처리함.

*/ + @Query("SELECT m FROM ObpGwMetric m WHERE m.timeslice = :timeslice " + + "AND (m.apiId = :apiId OR (m.apiId IS NULL AND :apiId IS NULL)) " + + "AND (m.clientId = :clientId OR (m.clientId IS NULL AND :clientId IS NULL)) " + + "AND (m.hostname = :hostname OR (m.hostname IS NULL AND :hostname IS NULL)) " + + "AND (m.orgId = :orgId OR (m.orgId IS NULL AND :orgId IS NULL))") + Optional findByUniqueKeyNullSafe( + @Param("timeslice") LocalDateTime timeslice, + @Param("apiId") String apiId, + @Param("clientId") String clientId, + @Param("hostname") String hostname, + @Param("orgId") String orgId + ); + + /** + * @deprecated NULL 비교 문제로 {@link #findByUniqueKeyNullSafe} 사용 권장 + */ + @Deprecated Optional findByTimesliceAndApiIdAndClientIdAndHostnameAndOrgId( LocalDateTime timeslice, String apiId,