1313import jakarta .persistence .PersistenceContext ;
1414import lombok .RequiredArgsConstructor ;
1515import lombok .extern .slf4j .Slf4j ;
16+ import org .springframework .dao .DataIntegrityViolationException ;
1617import org .springframework .stereotype .Service ;
1718import org .springframework .transaction .annotation .Transactional ;
1819
@@ -159,7 +160,11 @@ public void importStocksFromJson(String jsonFilePath) {
159160 int skippedCount = 0 ;
160161 for (Stock stock : newStocks ) {
161162 try {
163+ // 이전 저장을 DB에 반영하여 중복 체크 정확도 향상
164+ entityManager .flush ();
165+
162166 // symbol로 이미 존재하는지 다시 확인 (DB에서 직접 확인)
167+ // flush 후 조회하여 방금 저장된 종목도 확인 가능
163168 Optional <Stock > existingStock = stockRepository .findBySymbol (stock .getSymbol ());
164169 if (existingStock .isPresent ()) {
165170 // 이미 존재하면 업데이트로 처리
@@ -173,19 +178,47 @@ public void importStocksFromJson(String jsonFilePath) {
173178 existing .setOverseasSector (stock .getOverseasSector ());
174179 }
175180 stockRepository .save (existing );
181+ entityManager .flush (); // 업데이트 즉시 반영
176182 skippedCount ++;
177183 log .debug ("Stock already exists, updated: {}" , stock .getSymbol ());
178184 } else {
179185 // 새 종목 저장
180186 stockRepository .save (stock );
187+ entityManager .flush (); // 저장 즉시 반영하여 ID 확정
181188 savedCount ++;
182189 }
190+ } catch (DataIntegrityViolationException e ) {
191+ // 중복 키 오류 발생 시 기존 종목으로 처리
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 );
215+ skippedCount ++;
216+ }
183217 } catch (Exception e ) {
184218 log .warn ("Failed to save stock: {} - {}" , stock .getSymbol (), e .getMessage ());
185219 skippedCount ++;
186220 }
187221 }
188- entityManager .flush ();
189222 log .info ("Saved {} new stocks, {} skipped (already exists or error)" , savedCount , skippedCount );
190223 }
191224
0 commit comments