@@ -162,6 +162,7 @@ public void importStocksFromJson(String jsonFilePath) {
162162 try {
163163 // 이전 저장을 DB에 반영하여 중복 체크 정확도 향상
164164 entityManager .flush ();
165+ entityManager .clear (); // 영속성 컨텍스트 정리하여 배치 충돌 방지
165166
166167 // symbol로 이미 존재하는지 다시 확인 (DB에서 직접 확인)
167168 // flush 후 조회하여 방금 저장된 종목도 확인 가능
@@ -182,41 +183,26 @@ public void importStocksFromJson(String jsonFilePath) {
182183 skippedCount ++;
183184 log .debug ("Stock already exists, updated: {}" , stock .getSymbol ());
184185 } else {
185- // 새 종목 저장
186- stockRepository . save (stock );
186+ // 새 종목 저장 - persist를 직접 사용하여 배치 회피
187+ entityManager . persist (stock );
187188 entityManager .flush (); // 저장 즉시 반영하여 ID 확정
189+ entityManager .detach (stock ); // 저장 후 detach하여 다음 저장과 충돌 방지
188190 savedCount ++;
189191 }
190192 } catch (DataIntegrityViolationException e ) {
191193 // 중복 키 오류 발생 시 기존 종목으로 처리
192- log .warn ("Duplicate key detected for stock: {}, attempting to update existing" , stock .getSymbol ());
193- try {
194- Optional <Stock > existingStock = stockRepository .findBySymbol (stock .getSymbol ());
195- if (existingStock .isPresent ()) {
196- Stock existing = existingStock .get ();
197- existing .updateSymbolNameIfNull (stock .getSymbolName ());
198- existing .setValid (true );
199- if (stock .getDomesticSector () != null ) {
200- existing .setDomesticSector (stock .getDomesticSector ());
201- }
202- if (stock .getOverseasSector () != null ) {
203- existing .setOverseasSector (stock .getOverseasSector ());
204- }
205- stockRepository .save (existing );
206- entityManager .flush ();
207- skippedCount ++;
208- log .debug ("Stock updated after duplicate key error: {}" , stock .getSymbol ());
209- } else {
210- skippedCount ++;
211- log .warn ("Failed to find existing stock after duplicate key error: {}" , stock .getSymbol ());
212- }
213- } catch (Exception ex ) {
214- log .error ("Failed to handle duplicate key error for stock: {}" , stock .getSymbol (), ex );
194+ handleDuplicateKeyError (stock , e );
195+ skippedCount ++;
196+ } catch (Exception e ) {
197+ // 예외 메시지에 "Duplicate entry"가 포함되어 있는지 확인
198+ String errorMessage = e .getMessage ();
199+ if (errorMessage != null && errorMessage .contains ("Duplicate entry" )) {
200+ handleDuplicateKeyError (stock , e );
201+ skippedCount ++;
202+ } else {
203+ log .warn ("Failed to save stock: {} - {}" , stock .getSymbol (), errorMessage );
215204 skippedCount ++;
216205 }
217- } catch (Exception e ) {
218- log .warn ("Failed to save stock: {} - {}" , stock .getSymbol (), e .getMessage ());
219- skippedCount ++;
220206 }
221207 }
222208 log .info ("Saved {} new stocks, {} skipped (already exists or error)" , savedCount , skippedCount );
@@ -338,5 +324,34 @@ private Stock createStock(String symbol, String symbolName, String securityName,
338324 EXCHANGENUM exchangeNum , Boolean valid ) {
339325 return new Stock (symbol , symbolName , securityName , exchangeNum , valid );
340326 }
327+
328+ /**
329+ * 중복 키 오류 발생 시 기존 종목을 찾아 업데이트합니다.
330+ */
331+ private void handleDuplicateKeyError (Stock stock , Exception e ) {
332+ log .warn ("Duplicate key detected for stock: {}, attempting to update existing" , stock .getSymbol ());
333+ try {
334+ entityManager .clear (); // 영속성 컨텍스트 정리
335+ Optional <Stock > existingStock = stockRepository .findBySymbol (stock .getSymbol ());
336+ if (existingStock .isPresent ()) {
337+ Stock existing = existingStock .get ();
338+ existing .updateSymbolNameIfNull (stock .getSymbolName ());
339+ existing .setValid (true );
340+ if (stock .getDomesticSector () != null ) {
341+ existing .setDomesticSector (stock .getDomesticSector ());
342+ }
343+ if (stock .getOverseasSector () != null ) {
344+ existing .setOverseasSector (stock .getOverseasSector ());
345+ }
346+ stockRepository .save (existing );
347+ entityManager .flush ();
348+ log .debug ("Stock updated after duplicate key error: {}" , stock .getSymbol ());
349+ } else {
350+ log .warn ("Failed to find existing stock after duplicate key error: {}" , stock .getSymbol ());
351+ }
352+ } catch (Exception ex ) {
353+ log .error ("Failed to handle duplicate key error for stock: {}" , stock .getSymbol (), ex );
354+ }
355+ }
341356}
342357
0 commit comments