imad-project / imad-server

1 stars 0 forks source link

같은 작품(contents)가 DB에 두 번 저장되는 문제 #123

Closed NCookies closed 10 months ago

NCookies commented 10 months ago

{{baseUrl}}/api/contents/details?id=86031&type=tv 요청을 사용하여 작품을 검색하면 최초에는 TMDB API를 통해 데이터를 가져오고 DB에 저장한다. 이후 같은 요청을 받거나 DB에 저장된 contents_id로 조회를 하면 DB에서 데이터를 읽어와 클라이언트에 보내준다.

그러나 이 때 DB에 같은 작품이 두 번 이상 저장되면 이후 DB에서 데이터를 읽어올 때 에러가 발생한다.

Failed to complete request: org.springframework.dao.IncorrectResultSizeDataAccessException: query did not return a unique result: 2

DB에서 작품 데이터를 읽어올 때 tmdb id와 type을 기준으로 검색해서 읽어온다. 이 경우에는 작품을 중복해서 저장하기 때문에 위와 같은 에러가 발생하는 것이다.

이를 방지하기 위해서 DB에 작품 정보를 저장할 때 중복검사를 한 번 더 검토를 수행할 수 있도록 해야한다. (controller 단에서 중복 여부에 따라 걸러내기는 한다.)

NCookies commented 10 months ago

우선 응급조치로 DB에서 중복 저장된 데이터를 수동으로 삭제해주었다.

NCookies commented 10 months ago

************************************************************

Request received for GET '/api/contents/details?id=86031&type=tv':

org.apache.catalina.connector.RequestFacade@2ee9964d

servletPath:/api/contents/details
pathInfo:null
headers: 
host: www.ncookie.site
connection: keep-alive
accept: */*
user-agent: IMAD_Project/1.0 (quarang.IMAD-Project; build:6; iOS 16.6.0) Alamofire/5.6.4
accept-language: ko-KR;q=1.0, en-KR;q=0.9
authorization: .

Security filter chain: [
  DisableEncodeUrlFilter
  WebAsyncManagerIntegrationFilter
  SecurityContextHolderFilter
  HeaderWriterFilter
  JwtExceptionFilter
  LogoutFilter
  JwtAuthenticationFilter
  CustomJsonUsernamePasswordAuthenticationFilter
  OAuth2AuthorizationRequestRedirectFilter
  OAuth2LoginAuthenticationFilter
  RequestCacheAwareFilter
  SecurityContextHolderAwareRequestFilter
  AnonymousAuthenticationFilter
  SessionManagementFilter
  ExceptionTranslationFilter
  AuthorizationFilter
]

************************************************************

2023-11-15 16:56:57,226  INFO 3900 --- [https-jsse-nio-443-exec-6] c.n.i.g.j.f.JwtAuthenticationFilter      : checkAccessTokenAndAuthentication() 호출
2023-11-15 16:56:57,226  INFO 3900 --- [https-jsse-nio-443-exec-6] c.n.i.g.j.f.JwtAuthenticationFilter      : access token 검사 시행
2023-11-15 16:56:57,227  INFO 3900 --- [https-jsse-nio-443-exec-6] c.n.i.g.j.f.JwtAuthenticationFilter      : JWT 인증 성공
2023-11-15 16:56:57,228 DEBUG 3900 --- [https-jsse-nio-443-exec-6] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped to com.ncookie.imad.domain.contents.controller.ContentsController#getContentsDetails(String, Long, String)
2023-11-15 16:56:57,228 DEBUG 3900 --- [https-jsse-nio-443-exec-6] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped to com.ncookie.imad.domain.contents.controller.ContentsController#getContentsDetails(String, Long, String)
2023-11-15 16:56:57,228 DEBUG 3900 --- [https-jsse-nio-443-exec-6] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped to com.ncookie.imad.domain.contents.controller.ContentsController#getContentsDetails(String, Long, String)
2023-11-15 16:56:57,228 DEBUG 3900 --- [https-jsse-nio-443-exec-4] m.m.a.RequestResponseBodyMethodProcessor : Using 'application/json', given [*/*] and supported [application/json, application/*+json]
2023-11-15 16:56:57,228 DEBUG 3900 --- [https-jsse-nio-443-exec-6] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped to com.ncookie.imad.domain.contents.controller.ContentsController#getContentsDetails(String, Long, String)
2023-11-15 16:56:57,228 DEBUG 3900 --- [https-jsse-nio-443-exec-4] m.m.a.RequestResponseBodyMethodProcessor : Writing [com.ncookie.imad.global.dto.response.ApiResponse@7b70ad40]
2023-11-15 16:56:57,228 DEBUG 3900 --- [https-jsse-nio-443-exec-6] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped to com.ncookie.imad.domain.contents.controller.ContentsController#getContentsDetails(String, Long, String)
2023-11-15 16:56:57,228 DEBUG 3900 --- [https-jsse-nio-443-exec-6] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped to com.ncookie.imad.domain.contents.controller.ContentsController#getContentsDetails(String, Long, String)
2023-11-15 16:56:57,228 DEBUG 3900 --- [https-jsse-nio-443-exec-6] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped to com.ncookie.imad.domain.contents.controller.ContentsController#getContentsDetails(String, Long, String)
2023-11-15 16:56:57,228 DEBUG 3900 --- [https-jsse-nio-443-exec-6] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped to com.ncookie.imad.domain.contents.controller.ContentsController#getContentsDetails(String, Long, String)
2023-11-15 16:56:57,228 DEBUG 3900 --- [https-jsse-nio-443-exec-6] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped to com.ncookie.imad.domain.contents.controller.ContentsController#getContentsDetails(String, Long, String)
2023-11-15 16:56:57,228 DEBUG 3900 --- [https-jsse-nio-443-exec-6] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped to com.ncookie.imad.domain.contents.controller.ContentsController#getContentsDetails(String, Long, String)
2023-11-15 16:56:57,228 DEBUG 3900 --- [https-jsse-nio-443-exec-4] o.s.web.servlet.DispatcherServlet        : Completed 200 OK
2023-11-15 16:56:57,228 DEBUG 3900 --- [https-jsse-nio-443-exec-6] o.s.web.servlet.DispatcherServlet        : GET "/api/contents/details?id=86031&type=tv", parameters={masked}
2023-11-15 16:56:57,228 DEBUG 3900 --- [https-jsse-nio-443-exec-6] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped to com.ncookie.imad.domain.contents.controller.ContentsController#getContentsDetails(String, Long, String)
2023-11-15 16:56:57,230 DEBUG 3900 --- [https-jsse-nio-443-exec-6] c.n.i.global.openfeign.TmdbFeignClient   : [TmdbFeignClient#getTvDetailsById] ---> GET https://api.themoviedb.org/3/tv/86031?language=ko-kr&append_to_response=credits%2Cimages%2Cvideos HTTP/1.1
2023-11-15 16:56:57,230 DEBUG 3900 --- [https-jsse-nio-443-exec-6] c.n.i.global.openfeign.TmdbFeignClient   : [TmdbFeignClient#getTvDetailsById] Authorization: .
2023-11-15 16:56:57,231 DEBUG 3900 --- [https-jsse-nio-443-exec-6] c.n.i.global.openfeign.TmdbFeignClient   : [TmdbFeignClient#getTvDetailsById] ---> END HTTP (0-byte body)
2023-11-15 16:56:57,372 DEBUG 3900 --- [https-jsse-nio-443-exec-6] c.n.i.global.openfeign.TmdbFeignClient   : [TmdbFeignClient#getTvDetailsById] <--- HTTP/1.1 200 OK (141ms)
2023-11-15 16:56:57,372 DEBUG 3900 --- [https-jsse-nio-443-exec-2] c.n.i.global.openfeign.TmdbFeignClient   : [TmdbFeignClient#getTvDetailsById] <--- HTTP/1.1 200 OK (251ms)
2023-11-15 16:56:57,372 DEBUG 3900 --- [https-jsse-nio-443-exec-6] c.n.i.global.openfeign.TmdbFeignClient   : [TmdbFeignClient#getTvDetailsById] alt-svc: h3=":443"; ma=86400
2023-11-15 16:56:57,372 DEBUG 3900 --- [https-jsse-nio-443-exec-2] c.n.i.global.openfeign.TmdbFeignClient   : [TmdbFeignClient#getTvDetailsById] alt-svc: h3=":443"; ma=86400
2023-11-15 16:56:57,372 DEBUG 3900 --- [https-jsse-nio-443-exec-6] c.n.i.global.openfeign.TmdbFeignClient   : [TmdbFeignClient#getTvDetailsById] cache-control: public, max-age=3600
2023-11-15 16:56:57,372 DEBUG 3900 --- [https-jsse-nio-443-exec-2] c.n.i.global.openfeign.TmdbFeignClient   : [TmdbFeignClient#getTvDetailsById] cache-control: public, max-age=3600
2023-11-15 16:56:57,372 DEBUG 3900 --- [https-jsse-nio-443-exec-6] c.n.i.global.openfeign.TmdbFeignClient   : [TmdbFeignClient#getTvDetailsById] connection: keep-alive
2023-11-15 16:56:57,372 DEBUG 3900 --- [https-jsse-nio-443-exec-2] c.n.i.global.openfeign.TmdbFeignClient   : [TmdbFeignClient#getTvDetailsById] connection: keep-alive
2023-11-15 16:56:57,372 DEBUG 3900 --- [https-jsse-nio-443-exec-6] c.n.i.global.openfeign.TmdbFeignClient   : [TmdbFeignClient#getTvDetailsById] content-length: 9522
2023-11-15 16:56:57,372 DEBUG 3900 --- [https-jsse-nio-443-exec-2] c.n.i.global.openfeign.TmdbFeignClient   : [TmdbFeignClient#getTvDetailsById] content-length: 9522
2023-11-15 16:56:57,372 DEBUG 3900 --- [https-jsse-nio-443-exec-6] c.n.i.global.openfeign.TmdbFeignClient   : [TmdbFeignClient#getTvDetailsById] content-type: application/json;charset=utf-8
2023-11-15 16:56:57,372 DEBUG 3900 --- [https-jsse-nio-443-exec-2] c.n.i.global.openfeign.TmdbFeignClient   : [TmdbFeignClient#getTvDetailsById] content-type: application/json;charset=utf-8
2023-11-15 16:56:57,372 DEBUG 3900 --- [https-jsse-nio-443-exec-6] c.n.i.global.openfeign.TmdbFeignClient   : [TmdbFeignClient#getTvDetailsById] date: Wed, 15 Nov 2023 07:56:57 GMT
2023-11-15 16:56:57,372 DEBUG 3900 --- [https-jsse-nio-443-exec-2] c.n.i.global.openfeign.TmdbFeignClient   : [TmdbFeignClient#getTvDetailsById] date: Wed, 15 Nov 2023 07:56:57 GMT
2023-11-15 16:56:57,372 DEBUG 3900 --- [https-jsse-nio-443-exec-6] c.n.i.global.openfeign.TmdbFeignClient   : [TmdbFeignClient#getTvDetailsById] etag: W/"0f66c1fdda7e32061578cd0556587261"
2023-11-15 16:56:57,372 DEBUG 3900 --- [https-jsse-nio-443-exec-2] c.n.i.global.openfeign.TmdbFeignClient   : [TmdbFeignClient#getTvDetailsById] etag: W/"0f66c1fdda7e32061578cd0556587261"
2023-11-15 16:56:57,373 DEBUG 3900 --- [https-jsse-nio-443-exec-6] c.n.i.global.openfeign.TmdbFeignClient   : [TmdbFeignClient#getTvDetailsById] server: openresty
2023-11-15 16:56:57,373 DEBUG 3900 --- [https-jsse-nio-443-exec-2] c.n.i.global.openfeign.TmdbFeignClient   : [TmdbFeignClient#getTvDetailsById] server: openresty
2023-11-15 16:56:57,373 DEBUG 3900 --- [https-jsse-nio-443-exec-6] c.n.i.global.openfeign.TmdbFeignClient   : [TmdbFeignClient#getTvDetailsById] vary: Origin
2023-11-15 16:56:57,373 DEBUG 3900 --- [https-jsse-nio-443-exec-2] c.n.i.global.openfeign.TmdbFeignClient   : [TmdbFeignClient#getTvDetailsById] vary: Origin
2023-11-15 16:56:57,373 DEBUG 3900 --- [https-jsse-nio-443-exec-6] c.n.i.global.openfeign.TmdbFeignClient   : [TmdbFeignClient#getTvDetailsById] vary: Accept-Encoding
2023-11-15 16:56:57,373 DEBUG 3900 --- [https-jsse-nio-443-exec-2] c.n.i.global.openfeign.TmdbFeignClient   : [TmdbFeignClient#getTvDetailsById] vary: Accept-Encoding
2023-11-15 16:56:57,373 DEBUG 3900 --- [https-jsse-nio-443-exec-6] c.n.i.global.openfeign.TmdbFeignClient   : [TmdbFeignClient#getTvDetailsById] via: 1.1 98cc70c99d4e07b8cd37265dc48c5a54.cloudfront.net (CloudFront)
2023-11-15 16:56:57,373 DEBUG 3900 --- [https-jsse-nio-443-exec-2] c.n.i.global.openfeign.TmdbFeignClient   : [TmdbFeignClient#getTvDetailsById] via: 1.1 d21d7f64d4ce2d8fcbb5fbee217cca5a.cloudfront.net (CloudFront)
2023-11-15 16:56:57,373 DEBUG 3900 --- [https-jsse-nio-443-exec-6] c.n.i.global.openfeign.TmdbFeignClient   : [TmdbFeignClient#getTvDetailsById] x-amz-cf-id: cA4jp9wiy6hqBOmSJc1pV1NYjK16F3remEVQoFPD_nxpUyWNmKa3ug==
2023-11-15 16:56:57,373 DEBUG 3900 --- [https-jsse-nio-443-exec-6] c.n.i.global.openfeign.TmdbFeignClient   : [TmdbFeignClient#getTvDetailsById] x-amz-cf-pop: ICN57-P2
2023-11-15 16:56:57,373 DEBUG 3900 --- [https-jsse-nio-443-exec-6] c.n.i.global.openfeign.TmdbFeignClient   : [TmdbFeignClient#getTvDetailsById] x-cache: Hit from cloudfront
2023-11-15 16:56:57,373 DEBUG 3900 --- [https-jsse-nio-443-exec-6] c.n.i.global.openfeign.TmdbFeignClient   : [TmdbFeignClient#getTvDetailsById] 
2023-11-15 16:56:57,373 DEBUG 3900 --- [https-jsse-nio-443-exec-2] c.n.i.global.openfeign.TmdbFeignClient   : [TmdbFeignClient#getTvDetailsById] x-amz-cf-id: MKZ5m1rfHOWVIRibNWt8uGw6RxRbHFjVtmJLgIOqSYCWP6autM6h3g==
2023-11-15 16:56:57,373 DEBUG 3900 --- [https-jsse-nio-443-exec-2] c.n.i.global.openfeign.TmdbFeignClient   : [TmdbFeignClient#getTvDetailsById] x-amz-cf-pop: ICN57-P2
2023-11-15 16:56:57,373 DEBUG 3900 --- [https-jsse-nio-443-exec-2] c.n.i.global.openfeign.TmdbFeignClient   : [TmdbFeignClient#getTvDetailsById] x-cache: Miss from cloudfront
2023-11-15 16:56:57,373 DEBUG 3900 --- [https-jsse-nio-443-exec-2] c.n.i.global.openfeign.TmdbFeignClient   : [TmdbFeignClient#getTvDetailsById] 
2023-11-15 16:56:57,373 DEBUG 3900 --- [https-jsse-nio-443-exec-6] c.n.i.global.openfeign.TmdbFeignClient   : [TmdbFeignClient#getTvDetailsById] {"adult":false,"backdrop_path":"/lN13BPAEnc5iXmoxxBQHOZ1ScfZ.jpg","created_by":[],"episode_run_time":[24],"first_air_date":"2019-07-05","genres":[{"id":10759,"name":"Action & Adventure"},{"id":16,"name":"애니메이션"}],"homepage":"https://dr-stone.jp","id":86031,"in_production":true,"languages":["ja"],"last_air_date":"2023-11-09","last_episode_to_air":{"id":4810702,"name":"에피소드 16","overview":"","vote_average":0.0,"vote_count":0,"air_date":"2023-11-09","episode_number":16,"episode_type":"standard","production_code":"","runtime":24,"season_number":3,"show_id":86031,"still_path":"/uJGNLytepCwHWmUXl7MjPfOtZAa.jpg"},"name":"닥터 스톤","next_episode_to_air":{"id":4810712,"name":"에피소드 17","overview":"","vote_average":0.0,"vote_count":0,"air_date":"2023-11-16","episode_number":17,"episode_type":"standard","production_code":"","runtime":24,"season_number":3,"show_id":86031,"still_path":"/6v7V8kljFknyT2NhVRsHK9tESC1.jpg"},"networks":[{"id":614,"logo_path":"/hSdroyVthq3CynxTIIY7lnS8w1.png","name":"Tokyo MX","origin_country":"JP"},{"id":1137,"logo_path":"/j12pSWPsDBxE1mmIpB7M8VRzk78.png","name":"KBS Kyoto","origin_country":"JP"}],"number_of_episodes":53,"number_of_seasons":3,"origin_country":["JP"],"original_language":"ja","original_name":"Dr.STONE","overview":"돌로 변한 사람들. 세상은 그렇게 멈춰 버렸다. 그러나 절망 속에도 한줄기 희망이 살아있었으니. 과학 천재 소년 센쿠와 체력왕 타이주가 어둠을 깨고 분연히 일어난다. 문명의 재건을 위하여.","popularity":36.304,"poster_path":"/cu341PWYpVPplqPbsHZ0kaFPiQd.jpg","production_companies":[{"id":7164,"logo_path":"/vHsaqTkQ2ZTbdqrCA272YahoVlg.png","name":"TMS Entertainment","origin_country":"JP"},{"id":882,"logo_path":"/iDw9Xxok1d9WAM2zFicI8p3khTH.png","name":"TOHO","origin_country":"JP"},{"id":2918,"logo_path":"/gyEWUBWwqrm3H5T2hkERD9LxpOq.png","name":"Shueisha","origin_country":"JP"}],"production_countries":[{"iso_3166_1":"JP","name":"Japan"}],"seasons":[{"air_date":"2020-10-11","episode_count":3,"id":166462,"name":"스페셜","overview":"","poster_path":"/kCqFYFpB9Ojxke4CbfTO1q4MuoG.jpg","season_number":0,"vote_average":0.0},{"air_date":"2019-07-05","episode_count":24,"id":117113,"name":"시즌 1","overview":"어느 날, 지구상의 모든 인류가 돌이 되었다! 평범한 고등학생 타이주가 5년간 간직했던 짝사랑을 고백하려던 순간, 알 수 없는 힘이 인류를 덮쳐서 지구상의 모든 사람이 돌로 변해 버렸다. 그로부터 수천 년의 시간이 흐른 뒤, 겨우 깨어난 타이주는 자신의 친구인 천재 소년 센쿠와 다시 만난다. 인류가 이룩한 모든 문명이 ′제로′로 돌아간 이 시대에 살아남은 두 고등학생! 절망적인 상황이었지만 천재적인 두뇌를 지닌 센쿠는 과학의 힘으로 세상을 되돌려 놓겠다고 선언한다. 그리고 타이주와 함께 ′제로′에서부터 ′근대 문명′을 만들어 내기 시작하는데... 석기 시대부터 현대 문명까지 과학사 200만 년을 뛰어넘는 전대미문의 모험이 지금 이곳에서 시작된다!","poster_path":"/8kprUznHSw5VJyOd2lOtzwmowUM.jpg","season_number":1,"vote_average":7.5},{"air_date":"2021-01-14","episode_count":11,"id":164875,"name":"STONE WARS","overview":"인류가 200만 년간 쌓아 올린 문명이 멸망하고 모두가 돌로 변한 ′스톤 월드′. 그곳에서 초인적인 두뇌와 과학의 힘으로 문명을 만들어내는 ′센쿠′와 무력으로 과학을 제압하려는 ′츠카사′가 대립하는데…","poster_path":"/dVh0d8LaSJilxI3JhSNPof527oJ.jpg","season_number":2,"vote_average":7.1},{"air_date":"2023-04-06","episode_count":18,"id":300424,"name":"NEW WORLD","overview":"전대미문의 크라프트 어드벤처, 여기 개막!\n\n전 인류가 수수께끼의 현상에 의해 순식간에 석화되고 수천 년.\n\n초인적인 두뇌를 가진 천재 과학 소년 센쿠가 깨어났다.\n\n문명이 멸망한 스톤 월드 앞에서\n\n센쿠는 과학의 힘으로 세계를 되찾을 것을 결의.\n\n새로운 동료를 모아 ‘과학 왕국’을 만든다.\n\n하지만 그때 영장류 최강 고교생 시시오 츠카사가 이끄는\n\n‘무력 제국’이 앞길을 가로막는다.\n\n인류 정화를 목표로 강력한 무력을 앞세워 과학 발전을 저지하려는 츠카사.  과학 vs 무력의 싸움은 격투 끝에 센쿠 일행의 과학 왕국이 승리하고\n\n두 나라는 마침내 화해한다.\n\n동료의 배신으로 콜드 슬립 상태가 된 츠카사.\n\n그리고 전 인류를 부활시키기 위해\n\n과학 왕국은 석화 광선의 발생원, 지구의 뒤편인 신세계로 향한다.\n\n세계에 갑자기 나타난 석화의 수수께끼를 풀기 위해서\n\n스톤 월드 대항해 시대가 드디어 시작된다!","poster_path":"/vyE7gJceFqz6uImrttulJHdbTdi.jpg","season_number":3,"vote_average":8.3}],"spoken_languages":[{"english_name":"Japanese","iso_639_1":"ja","name":"日本語"}],"status":"Returning Series","tagline":"","type":"Scripted","vote_average":8.61,"vote_count":1276,"credits":{"cast":[{"adult":false,"gender":2,"id":1350418,"known_for_department":"Acting","name":"Yusuke Kobayashi","original_name":"Yusuke Kobayashi","popularity":13.418,"profile_path":"/r5hRCRBz1kMPBIVERUYPzwHPaIN.jpg","character":"Senku Ishigami (voice)","credit_id":"5d2928a0caab6d00129d2bcb","order":0}],"crew":[{"adult":false,"gender":2,"id":2458967,"known_for_department":"Directing","name":"Shuhei Matsushita","original_name":"Shuhei Matsushita","popularity":2.201,"profile_path":null,"credit_id":"64234d67fcb8cc00f4335c58","department":"Directing","job":"Series Director"},{"adult":false,"gender":2,"id":1297620,"known_for_department":"Visual Effects","name":"Hiroyuki Horiuchi","original_name":"Hiroyuki Horiuchi","popularity":3.729,"profile_path":null,"credit_id":"64234f0bd19a3300b43c47f4","department":"Visual Effects","job":"Lead Animator"},{"adult":false,"gender":0,"id":1846718,"known_for_department":"Art","name":"Tomoyuki Aoki","original_name":"Tomoyuki Aoki","popularity":1.4,"profile_path":null,"credit_id":"64234f266d97e600bc8c233e","department":"Art","job":"Art Designer"},{"adult":false,"gender":1,"id":90258,"known_for_department":"Editing","name":"Kumiko Sakamoto","original_name":"Kumiko Sakamoto","popularity":0.973,"profile_path":null,"credit_id":"5f7f00be3429ff0037c6a4a6","department":"Editing","job":"Editor"},{"adult":false,"gender":0,"id":3297985,"known_for_department":"Camera","name":"Kim Kwang-jun","original_name":"Kim Kwang-jun","popularity":0.6,"profile_path":null,"credit_id":"6184fd7bddd52d006162fa3b","department":"Camera","job":"Director of Photography"},{"adult":false,"gender":2,"id":570486,"known_for_department":"Sound","name":"Jin Aketagawa","original_name":"Jin Aketagawa","popularity":11.824,"profile_path":null,"credit_id":"5f7efe83b7abb500376929ae","department":"Sound","job":"Sound Director"},{"adult":false,"gender":2,"id":126264,"known_for_department":"Art","name":"Shunichiro Yoshihara","original_name":"Shunichiro Yoshihara","popularity":3.864,"profile_path":"/agcngp45HqRzjfLmi7AChuT9VOC.jpg","credit_id":"5f7effc6d11e0e0036be1f47","department":"Art","job":"Art Direction"},{"adult":false,"gender":2,"id":1316011,"known_for_department":"Sound","name":"Tatsuya Kato","original_name":"Tatsuya Kato","popularity":5.894,"profile_path":"/7tbWGtNW3ThuuXE5Gdehp77Twj1.jpg","credit_id":"5f7efe45d11e0e0037bffb47","department":"Sound","job":"Original Music Composer"},{"adult":false,"gender":2,"id":2807903,"known_for_department":"Sound","name":"Yuki Kanesaka","original_name":"Yuki Kanesaka","popularity":1.22,"profile_path":null,"credit_id":"5f7efe72d11e0e0038bd8bb0","department":"Sound","job":"Original Music Composer"},{"adult":false,"gender":1,"id":2807904,"known_for_department":"Visual Effects","name":"Yuko Iwasa","original_name":"Yuko Iwasa","popularity":0.888,"profile_path":null,"credit_id":"5f7effbdb7abb500386d5906","department":"Visual Effects","job":"Character Designer"},{"adult":false,"gender":2,"id":1641415,"known_for_department":"Writing","name":"Riichiro Inagaki","original_name":"Riichiro Inagaki","popularity":1.041,"profile_path":null,"credit_id":"5f7efff0d11e0e0035bef063","department":"Writing","job":"Comic Book"},{"adult":false,"gender":2,"id":1842749,"known_for_department":"Writing","name":"Yuichiro Kido","original_name":"Yuichiro Kido","popularity":1.739,"profile_path":null,"credit_id":"5f7eff9a2667780036b11bcf","department":"Writing","job":"Series Composition"},{"adult":false,"gender":2,"id":1493763,"known_for_department":"Sound","name":"Hiroaki Tsutsumi","original_name":"Hiroaki Tsutsumi","popularity":1.745,"profile_path":"/gjZTF2jtGqvGY4F6XywHCweVkMb.jpg","credit_id":"5f7efe2dc8113d0038aa861b","department":"Sound","job":"Original Music Composer"},{"adult":false,"gender":1,"id":1982967,"known_for_department":"Visual Effects","name":"Fusako Nakao","original_name":"Fusako Nakao","popularity":1.96,"profile_path":null,"credit_id":"6184fea413a3880096d4d8dd","department":"Visual Effects","job":"Color Designer"},{"adult":false,"gender":2,"id":3884016,"known_for_department":"Visual Effects","name":"Boichi","original_name":"Boichi","popularity":0.6,"profile_path":null,"credit_id":"6423500612eb8900f5e07dda","department":"Visual Effects","job":"Character Designer"}]},"images":{"backdrops":[],"logos":[],"posters":[]},"videos":{"results":[]}}
2023-11-15 16:56:57,373 DEBUG 3900 --- [https-jsse-nio-443-exec-6] c.n.i.global.openfeign.TmdbFeignClient   : [TmdbFeignClient#getTvDetailsById] <--- END HTTP (9522-byte body)
2023-11-15 16:56:57,373 DEBUG 3900 --- [https-jsse-nio-443-exec-2] c.n.i.global.openfeign.TmdbFeignClient   : [TmdbFeignClient#getTvDetailsById] {"adult":false,"backdrop_path":"/lN13BPAEnc5iXmoxxBQHOZ1ScfZ.jpg","created_by":[],"episode_run_time":[24],"first_air_date":"2019-07-05","genres":[{"id":10759,"name":"Action & Adventure"},{"id":16,"name":"애니메이션"}],"homepage":"https://dr-stone.jp","id":86031,"in_production":true,"languages":["ja"],"last_air_date":"2023-11-09","last_episode_to_air":{"id":4810702,"name":"에피소드 16","overview":"","vote_average":0.0,"vote_count":0,"air_date":"2023-11-09","episode_number":16,"episode_type":"standard","production_code":"","runtime":24,"season_number":3,"show_id":86031,"still_path":"/uJGNLytepCwHWmUXl7MjPfOtZAa.jpg"},"name":"닥터 스톤","next_episode_to_air":{"id":4810712,"name":"에피소드 17","overview":"","vote_average":0.0,"vote_count":0,"air_date":"2023-11-16","episode_number":17,"episode_type":"standard","production_code":"","runtime":24,"season_number":3,"show_id":86031,"still_path":"/6v7V8kljFknyT2NhVRsHK9tESC1.jpg"},"networks":[{"id":614,"logo_path":"/hSdroyVthq3CynxTIIY7lnS8w1.png","name":"Tokyo MX","origin_country":"JP"},{"id":1137,"logo_path":"/j12pSWPsDBxE1mmIpB7M8VRzk78.png","name":"KBS Kyoto","origin_country":"JP"}],"number_of_episodes":53,"number_of_seasons":3,"origin_country":["JP"],"original_language":"ja","original_name":"Dr.STONE","overview":"돌로 변한 사람들. 세상은 그렇게 멈춰 버렸다. 그러나 절망 속에도 한줄기 희망이 살아있었으니. 과학 천재 소년 센쿠와 체력왕 타이주가 어둠을 깨고 분연히 일어난다. 문명의 재건을 위하여.","popularity":36.304,"poster_path":"/cu341PWYpVPplqPbsHZ0kaFPiQd.jpg","production_companies":[{"id":7164,"logo_path":"/vHsaqTkQ2ZTbdqrCA272YahoVlg.png","name":"TMS Entertainment","origin_country":"JP"},{"id":882,"logo_path":"/iDw9Xxok1d9WAM2zFicI8p3khTH.png","name":"TOHO","origin_country":"JP"},{"id":2918,"logo_path":"/gyEWUBWwqrm3H5T2hkERD9LxpOq.png","name":"Shueisha","origin_country":"JP"}],"production_countries":[{"iso_3166_1":"JP","name":"Japan"}],"seasons":[{"air_date":"2020-10-11","episode_count":3,"id":166462,"name":"스페셜","overview":"","poster_path":"/kCqFYFpB9Ojxke4CbfTO1q4MuoG.jpg","season_number":0,"vote_average":0.0},{"air_date":"2019-07-05","episode_count":24,"id":117113,"name":"시즌 1","overview":"어느 날, 지구상의 모든 인류가 돌이 되었다! 평범한 고등학생 타이주가 5년간 간직했던 짝사랑을 고백하려던 순간, 알 수 없는 힘이 인류를 덮쳐서 지구상의 모든 사람이 돌로 변해 버렸다. 그로부터 수천 년의 시간이 흐른 뒤, 겨우 깨어난 타이주는 자신의 친구인 천재 소년 센쿠와 다시 만난다. 인류가 이룩한 모든 문명이 ′제로′로 돌아간 이 시대에 살아남은 두 고등학생! 절망적인 상황이었지만 천재적인 두뇌를 지닌 센쿠는 과학의 힘으로 세상을 되돌려 놓겠다고 선언한다. 그리고 타이주와 함께 ′제로′에서부터 ′근대 문명′을 만들어 내기 시작하는데... 석기 시대부터 현대 문명까지 과학사 200만 년을 뛰어넘는 전대미문의 모험이 지금 이곳에서 시작된다!","poster_path":"/8kprUznHSw5VJyOd2lOtzwmowUM.jpg","season_number":1,"vote_average":7.5},{"air_date":"2021-01-14","episode_count":11,"id":164875,"name":"STONE WARS","overview":"인류가 200만 년간 쌓아 올린 문명이 멸망하고 모두가 돌로 변한 ′스톤 월드′. 그곳에서 초인적인 두뇌와 과학의 힘으로 문명을 만들어내는 ′센쿠′와 무력으로 과학을 제압하려는 ′츠카사′가 대립하는데…","poster_path":"/dVh0d8LaSJilxI3JhSNPof527oJ.jpg","season_number":2,"vote_average":7.1},{"air_date":"2023-04-06","episode_count":18,"id":300424,"name":"NEW WORLD","overview":"전대미문의 크라프트 어드벤처, 여기 개막!\n\n전 인류가 수수께끼의 현상에 의해 순식간에 석화되고 수천 년.\n\n초인적인 두뇌를 가진 천재 과학 소년 센쿠가 깨어났다.\n\n문명이 멸망한 스톤 월드 앞에서\n\n센쿠는 과학의 힘으로 세계를 되찾을 것을 결의.\n\n새로운 동료를 모아 ‘과학 왕국’을 만든다.\n\n하지만 그때 영장류 최강 고교생 시시오 츠카사가 이끄는\n\n‘무력 제국’이 앞길을 가로막는다.\n\n인류 정화를 목표로 강력한 무력을 앞세워 과학 발전을 저지하려는 츠카사.  과학 vs 무력의 싸움은 격투 끝에 센쿠 일행의 과학 왕국이 승리하고\n\n두 나라는 마침내 화해한다.\n\n동료의 배신으로 콜드 슬립 상태가 된 츠카사.\n\n그리고 전 인류를 부활시키기 위해\n\n과학 왕국은 석화 광선의 발생원, 지구의 뒤편인 신세계로 향한다.\n\n세계에 갑자기 나타난 석화의 수수께끼를 풀기 위해서\n\n스톤 월드 대항해 시대가 드디어 시작된다!","poster_path":"/vyE7gJceFqz6uImrttulJHdbTdi.jpg","season_number":3,"vote_average":8.3}],"spoken_languages":[{"english_name":"Japanese","iso_639_1":"ja","name":"日本語"}],"status":"Returning Series","tagline":"","type":"Scripted","vote_average":8.61,"vote_count":1276,"credits":{"cast":[{"adult":false,"gender":2,"id":1350418,"known_for_department":"Acting","name":"Yusuke Kobayashi","original_name":"Yusuke Kobayashi","popularity":13.418,"profile_path":"/r5hRCRBz1kMPBIVERUYPzwHPaIN.jpg","character":"Senku Ishigami (voice)","credit_id":"5d2928a0caab6d00129d2bcb","order":0}],"crew":[{"adult":false,"gender":2,"id":2458967,"known_for_department":"Directing","name":"Shuhei Matsushita","original_name":"Shuhei Matsushita","popularity":2.201,"profile_path":null,"credit_id":"64234d67fcb8cc00f4335c58","department":"Directing","job":"Series Director"},{"adult":false,"gender":2,"id":1297620,"known_for_department":"Visual Effects","name":"Hiroyuki Horiuchi","original_name":"Hiroyuki Horiuchi","popularity":3.729,"profile_path":null,"credit_id":"64234f0bd19a3300b43c47f4","department":"Visual Effects","job":"Lead Animator"},{"adult":false,"gender":0,"id":1846718,"known_for_department":"Art","name":"Tomoyuki Aoki","original_name":"Tomoyuki Aoki","popularity":1.4,"profile_path":null,"credit_id":"64234f266d97e600bc8c233e","department":"Art","job":"Art Designer"},{"adult":false,"gender":1,"id":90258,"known_for_department":"Editing","name":"Kumiko Sakamoto","original_name":"Kumiko Sakamoto","popularity":0.973,"profile_path":null,"credit_id":"5f7f00be3429ff0037c6a4a6","department":"Editing","job":"Editor"},{"adult":false,"gender":0,"id":3297985,"known_for_department":"Camera","name":"Kim Kwang-jun","original_name":"Kim Kwang-jun","popularity":0.6,"profile_path":null,"credit_id":"6184fd7bddd52d006162fa3b","department":"Camera","job":"Director of Photography"},{"adult":false,"gender":2,"id":570486,"known_for_department":"Sound","name":"Jin Aketagawa","original_name":"Jin Aketagawa","popularity":11.824,"profile_path":null,"credit_id":"5f7efe83b7abb500376929ae","department":"Sound","job":"Sound Director"},{"adult":false,"gender":2,"id":126264,"known_for_department":"Art","name":"Shunichiro Yoshihara","original_name":"Shunichiro Yoshihara","popularity":3.864,"profile_path":"/agcngp45HqRzjfLmi7AChuT9VOC.jpg","credit_id":"5f7effc6d11e0e0036be1f47","department":"Art","job":"Art Direction"},{"adult":false,"gender":2,"id":1316011,"known_for_department":"Sound","name":"Tatsuya Kato","original_name":"Tatsuya Kato","popularity":5.894,"profile_path":"/7tbWGtNW3ThuuXE5Gdehp77Twj1.jpg","credit_id":"5f7efe45d11e0e0037bffb47","department":"Sound","job":"Original Music Composer"},{"adult":false,"gender":2,"id":2807903,"known_for_department":"Sound","name":"Yuki Kanesaka","original_name":"Yuki Kanesaka","popularity":1.22,"profile_path":null,"credit_id":"5f7efe72d11e0e0038bd8bb0","department":"Sound","job":"Original Music Composer"},{"adult":false,"gender":1,"id":2807904,"known_for_department":"Visual Effects","name":"Yuko Iwasa","original_name":"Yuko Iwasa","popularity":0.888,"profile_path":null,"credit_id":"5f7effbdb7abb500386d5906","department":"Visual Effects","job":"Character Designer"},{"adult":false,"gender":2,"id":1641415,"known_for_department":"Writing","name":"Riichiro Inagaki","original_name":"Riichiro Inagaki","popularity":1.041,"profile_path":null,"credit_id":"5f7efff0d11e0e0035bef063","department":"Writing","job":"Comic Book"},{"adult":false,"gender":2,"id":1842749,"known_for_department":"Writing","name":"Yuichiro Kido","original_name":"Yuichiro Kido","popularity":1.739,"profile_path":null,"credit_id":"5f7eff9a2667780036b11bcf","department":"Writing","job":"Series Composition"},{"adult":false,"gender":2,"id":1493763,"known_for_department":"Sound","name":"Hiroaki Tsutsumi","original_name":"Hiroaki Tsutsumi","popularity":1.745,"profile_path":"/gjZTF2jtGqvGY4F6XywHCweVkMb.jpg","credit_id":"5f7efe2dc8113d0038aa861b","department":"Sound","job":"Original Music Composer"},{"adult":false,"gender":1,"id":1982967,"known_for_department":"Visual Effects","name":"Fusako Nakao","original_name":"Fusako Nakao","popularity":1.96,"profile_path":null,"credit_id":"6184fea413a3880096d4d8dd","department":"Visual Effects","job":"Color Designer"},{"adult":false,"gender":2,"id":3884016,"known_for_department":"Visual Effects","name":"Boichi","original_name":"Boichi","popularity":0.6,"profile_path":null,"credit_id":"6423500612eb8900f5e07dda","department":"Visual Effects","job":"Character Designer"}]},"images":{"backdrops":[],"logos":[],"posters":[]},"videos":{"results":[]}}
2023-11-15 16:56:57,373 DEBUG 3900 --- [https-jsse-nio-443-exec-2] c.n.i.global.openfeign.TmdbFeignClient   : [TmdbFeignClient#getTvDetailsById] <--- END HTTP (9522-byte body)
2023-11-15 16:56:57,376 DEBUG 3900 --- [https-jsse-nio-443-exec-6] c.n.i.global.openfeign.TmdbFeignClient   : [TmdbFeignClient#getTvCertification] ---> GET https://api.themoviedb.org/3/tv/86031/content_ratings HTTP/1.1
2023-11-15 16:56:57,376 DEBUG 3900 --- [https-jsse-nio-443-exec-2] c.n.i.global.openfeign.TmdbFeignClient   : [TmdbFeignClient#getTvCertification] ---> GET https://api.themoviedb.org/3/tv/86031/content_ratings HTTP/1.1
2023-11-15 16:56:57,376 DEBUG 3900 --- [https-jsse-nio-443-exec-6] c.n.i.global.openfeign.TmdbFeignClient   : [TmdbFeignClient#getTvCertification] Authorization:.
2023-11-15 16:56:57,376 DEBUG 3900 --- [https-jsse-nio-443-exec-2] c.n.i.global.openfeign.TmdbFeignClient   : [TmdbFeignClient#getTvCertification] Authorization: .
2023-11-15 16:56:57,376 DEBUG 3900 --- [https-jsse-nio-443-exec-6] c.n.i.global.openfeign.TmdbFeignClient   : [TmdbFeignClient#getTvCertification] ---> END HTTP (0-byte body)
2023-11-15 16:56:57,376 DEBUG 3900 --- [https-jsse-nio-443-exec-2] c.n.i.global.openfeign.TmdbFeignClient   : [TmdbFeignClient#getTvCertification] ---> END HTTP (0-byte body)
2023-11-15 16:56:57,585 DEBUG 3900 --- [https-jsse-nio-443-exec-2] c.n.i.global.openfeign.TmdbFeignClient   : [TmdbFeignClient#getTvCertification] <--- HTTP/1.1 200 OK (208ms)
2023-11-15 16:56:57,585 DEBUG 3900 --- [https-jsse-nio-443-exec-2] c.n.i.global.openfeign.TmdbFeignClient   : [TmdbFeignClient#getTvCertification] alt-svc: h3=":443"; ma=86400
2023-11-15 16:56:57,585 DEBUG 3900 --- [https-jsse-nio-443-exec-2] c.n.i.global.openfeign.TmdbFeignClient   : [TmdbFeignClient#getTvCertification] connection: keep-alive
2023-11-15 16:56:57,585 DEBUG 3900 --- [https-jsse-nio-443-exec-2] c.n.i.global.openfeign.TmdbFeignClient   : [TmdbFeignClient#getTvCertification] content-length: 386
2023-11-15 16:56:57,585 DEBUG 3900 --- [https-jsse-nio-443-exec-2] c.n.i.global.openfeign.TmdbFeignClient   : [TmdbFeignClient#getTvCertification] content-type: application/json;charset=utf-8
2023-11-15 16:56:57,585 DEBUG 3900 --- [https-jsse-nio-443-exec-2] c.n.i.global.openfeign.TmdbFeignClient   : [TmdbFeignClient#getTvCertification] date: Wed, 15 Nov 2023 07:56:57 GMT
2023-11-15 16:56:57,585 DEBUG 3900 --- [https-jsse-nio-443-exec-2] c.n.i.global.openfeign.TmdbFeignClient   : [TmdbFeignClient#getTvCertification] etag: W/"7e78bd6b6d92cffd10a3a288a31eb8cf"
2023-11-15 16:56:57,585 DEBUG 3900 --- [https-jsse-nio-443-exec-2] c.n.i.global.openfeign.TmdbFeignClient   : [TmdbFeignClient#getTvCertification] server: openresty
2023-11-15 16:56:57,585 DEBUG 3900 --- [https-jsse-nio-443-exec-2] c.n.i.global.openfeign.TmdbFeignClient   : [TmdbFeignClient#getTvCertification] vary: Origin
2023-11-15 16:56:57,585 DEBUG 3900 --- [https-jsse-nio-443-exec-2] c.n.i.global.openfeign.TmdbFeignClient   : [TmdbFeignClient#getTvCertification] vary: Accept-Encoding
2023-11-15 16:56:57,585 DEBUG 3900 --- [https-jsse-nio-443-exec-2] c.n.i.global.openfeign.TmdbFeignClient   : [TmdbFeignClient#getTvCertification] via: 1.1 d21d7f64d4ce2d8fcbb5fbee217cca5a.cloudfront.net (CloudFront)
2023-11-15 16:56:57,585 DEBUG 3900 --- [https-jsse-nio-443-exec-2] c.n.i.global.openfeign.TmdbFeignClient   : [TmdbFeignClient#getTvCertification] x-amz-cf-id: _rMMLmY_X7Fb3tPi0Kyudk8poc8FoFmBUa04MkZUmZTE6FFT-TtEuA==
2023-11-15 16:56:57,585 DEBUG 3900 --- [https-jsse-nio-443-exec-2] c.n.i.global.openfeign.TmdbFeignClient   : [TmdbFeignClient#getTvCertification] x-amz-cf-pop: ICN57-P2
2023-11-15 16:56:57,585 DEBUG 3900 --- [https-jsse-nio-443-exec-2] c.n.i.global.openfeign.TmdbFeignClient   : [TmdbFeignClient#getTvCertification] x-cache: Miss from cloudfront
2023-11-15 16:56:57,585 DEBUG 3900 --- [https-jsse-nio-443-exec-2] c.n.i.global.openfeign.TmdbFeignClient   : [TmdbFeignClient#getTvCertification] x-memc: HIT
2023-11-15 16:56:57,585 DEBUG 3900 --- [https-jsse-nio-443-exec-2] c.n.i.global.openfeign.TmdbFeignClient   : [TmdbFeignClient#getTvCertification] x-memc-age: 8573
2023-11-15 16:56:57,585 DEBUG 3900 --- [https-jsse-nio-443-exec-2] c.n.i.global.openfeign.TmdbFeignClient   : [TmdbFeignClient#getTvCertification] x-memc-expires: 14421
2023-11-15 16:56:57,585 DEBUG 3900 --- [https-jsse-nio-443-exec-2] c.n.i.global.openfeign.TmdbFeignClient   : [TmdbFeignClient#getTvCertification] x-memc-key: f89821ea69ab540cd28951139cffd4b4
2023-11-15 16:56:57,585 DEBUG 3900 --- [https-jsse-nio-443-exec-2] c.n.i.global.openfeign.TmdbFeignClient   : [TmdbFeignClient#getTvCertification] 
2023-11-15 16:56:57,586 DEBUG 3900 --- [https-jsse-nio-443-exec-2] c.n.i.global.openfeign.TmdbFeignClient   : [TmdbFeignClient#getTvCertification] {"results":[{"descriptors":[],"iso_3166_1":"DE","rating":"12"},{"descriptors":[],"iso_3166_1":"KR","rating":"15"},{"descriptors":[],"iso_3166_1":"GB","rating":"12"},{"descriptors":[],"iso_3166_1":"BR","rating":"14"},{"descriptors":[],"iso_3166_1":"ES","rating":"13"},{"descriptors":[],"iso_3166_1":"US","rating":"TV-14"},{"descriptors":[],"iso_3166_1":"SG","rating":"NC16"}],"id":86031}
2023-11-15 16:56:57,586 DEBUG 3900 --- [https-jsse-nio-443-exec-2] c.n.i.global.openfeign.TmdbFeignClient   : [TmdbFeignClient#getTvCertification] <--- END HTTP (386-byte body)
2023-11-15 16:56:57,586  INFO 3900 --- [https-jsse-nio-443-exec-2] c.n.i.domain.tmdb.service.TmdbService    : TV 데이터 DB 저장 시작 : [86031] 닥터 스톤
2023-11-15 16:56:57,588  INFO 3900 --- [https-jsse-nio-443-exec-2] c.n.i.domain.tmdb.service.TmdbService    : TV 데이터 DB 저장 완료 : [86031] 닥터 스톤
2023-11-15 16:56:57,588  INFO 3900 --- [https-jsse-nio-443-exec-2] c.n.i.domain.tmdb.service.TmdbService    : SEASON 정보 DB 저장 시작
2023-11-15 16:56:57,602  INFO 3900 --- [https-jsse-nio-443-exec-2] c.n.i.domain.tmdb.service.TmdbService    : SEASON 정보 DB 저장 완료
2023-11-15 16:56:57,602  INFO 3900 --- [https-jsse-nio-443-exec-2] c.n.i.domain.tmdb.service.TmdbService    : 방송자 정보 DB 저장 시작
2023-11-15 16:56:57,605  INFO 3900 --- [https-jsse-nio-443-exec-2] c.n.i.domain.tmdb.service.TmdbService    : 방송자 정보 DB 저장 완료
2023-11-15 16:56:57,605  INFO 3900 --- [https-jsse-nio-443-exec-2] c.n.i.domain.tmdb.service.TmdbService    : Credits 정보 DB 저장 시작
2023-11-15 16:56:57,606  INFO 3900 --- [https-jsse-nio-443-exec-2] c.n.i.domain.tmdb.service.TmdbService    : Credits 정보 DB 저장 완료
2023-11-15 16:56:57,606  INFO 3900 --- [https-jsse-nio-443-exec-2] c.n.i.domain.tmdb.service.TmdbService    : TMDB API details 및 credits 정보 DB 저장 완료
2023-11-15 16:56:57,615 DEBUG 3900 --- [https-jsse-nio-443-exec-2] m.m.a.RequestResponseBodyMethodProcessor : Using 'application/json', given [*/*] and supported [application/json, application/*+json]
2023-11-15 16:56:57,615 DEBUG 3900 --- [https-jsse-nio-443-exec-2] m.m.a.RequestResponseBodyMethodProcessor : Writing [com.ncookie.imad.global.dto.response.ApiResponse@19d5cd5c]
2023-11-15 16:56:57,616 DEBUG 3900 --- [https-jsse-nio-443-exec-2] o.s.web.servlet.DispatcherServlet        : Completed 200 OK
2023-11-15 16:56:57,789 DEBUG 3900 --- [https-jsse-nio-443-exec-6] c.n.i.global.openfeign.TmdbFeignClient   : [TmdbFeignClient#getTvCertification] <--- HTTP/1.1 200 OK (413ms)
2023-11-15 16:56:57,789 DEBUG 3900 --- [https-jsse-nio-443-exec-6] c.n.i.global.openfeign.TmdbFeignClient   : [TmdbFeignClient#getTvCertification] alt-svc: h3=":443"; ma=86400
2023-11-15 16:56:57,789 DEBUG 3900 --- [https-jsse-nio-443-exec-6] c.n.i.global.openfeign.TmdbFeignClient   : [TmdbFeignClient#getTvCertification] connection: keep-alive
2023-11-15 16:56:57,789 DEBUG 3900 --- [https-jsse-nio-443-exec-6] c.n.i.global.openfeign.TmdbFeignClient   : [TmdbFeignClient#getTvCertification] content-length: 386
2023-11-15 16:56:57,789 DEBUG 3900 --- [https-jsse-nio-443-exec-6] c.n.i.global.openfeign.TmdbFeignClient   : [TmdbFeignClient#getTvCertification] content-type: application/json;charset=utf-8
2023-11-15 16:56:57,789 DEBUG 3900 --- [https-jsse-nio-443-exec-6] c.n.i.global.openfeign.TmdbFeignClient   : [TmdbFeignClient#getTvCertification] date: Wed, 15 Nov 2023 07:56:57 GMT
2023-11-15 16:56:57,789 DEBUG 3900 --- [https-jsse-nio-443-exec-6] c.n.i.global.openfeign.TmdbFeignClient   : [TmdbFeignClient#getTvCertification] etag: W/"7e78bd6b6d92cffd10a3a288a31eb8cf"
2023-11-15 16:56:57,789 DEBUG 3900 --- [https-jsse-nio-443-exec-6] c.n.i.global.openfeign.TmdbFeignClient   : [TmdbFeignClient#getTvCertification] server: openresty
2023-11-15 16:56:57,789 DEBUG 3900 --- [https-jsse-nio-443-exec-6] c.n.i.global.openfeign.TmdbFeignClient   : [TmdbFeignClient#getTvCertification] vary: Origin
2023-11-15 16:56:57,789 DEBUG 3900 --- [https-jsse-nio-443-exec-6] c.n.i.global.openfeign.TmdbFeignClient   : [TmdbFeignClient#getTvCertification] vary: Accept-Encoding
2023-11-15 16:56:57,789 DEBUG 3900 --- [https-jsse-nio-443-exec-6] c.n.i.global.openfeign.TmdbFeignClient   : [TmdbFeignClient#getTvCertification] via: 1.1 98cc70c99d4e07b8cd37265dc48c5a54.cloudfront.net (CloudFront)
2023-11-15 16:56:57,789 DEBUG 3900 --- [https-jsse-nio-443-exec-6] c.n.i.global.openfeign.TmdbFeignClient   : [TmdbFeignClient#getTvCertification] x-amz-cf-id: 8AvSZl1zzA9eAPzobKBlAbMUEXSTdaB0JYgkyOfrcID74FSxMlOQ0A==
2023-11-15 16:56:57,789 DEBUG 3900 --- [https-jsse-nio-443-exec-6] c.n.i.global.openfeign.TmdbFeignClient   : [TmdbFeignClient#getTvCertification] x-amz-cf-pop: ICN57-P2
2023-11-15 16:56:57,789 DEBUG 3900 --- [https-jsse-nio-443-exec-6] c.n.i.global.openfeign.TmdbFeignClient   : [TmdbFeignClient#getTvCertification] x-cache: RefreshHit from cloudfront
2023-11-15 16:56:57,789 DEBUG 3900 --- [https-jsse-nio-443-exec-6] c.n.i.global.openfeign.TmdbFeignClient   : [TmdbFeignClient#getTvCertification] x-memc: HIT
2023-11-15 16:56:57,789 DEBUG 3900 --- [https-jsse-nio-443-exec-6] c.n.i.global.openfeign.TmdbFeignClient   : [TmdbFeignClient#getTvCertification] x-memc-age: 8573
2023-11-15 16:56:57,789 DEBUG 3900 --- [https-jsse-nio-443-exec-6] c.n.i.global.openfeign.TmdbFeignClient   : [TmdbFeignClient#getTvCertification] x-memc-expires: 14421
2023-11-15 16:56:57,789 DEBUG 3900 --- [https-jsse-nio-443-exec-6] c.n.i.global.openfeign.TmdbFeignClient   : [TmdbFeignClient#getTvCertification] x-memc-key: f89821ea69ab540cd28951139cffd4b4
2023-11-15 16:56:57,789 DEBUG 3900 --- [https-jsse-nio-443-exec-6] c.n.i.global.openfeign.TmdbFeignClient   : [TmdbFeignClient#getTvCertification] 
2023-11-15 16:56:57,789 DEBUG 3900 --- [https-jsse-nio-443-exec-6] c.n.i.global.openfeign.TmdbFeignClient   : [TmdbFeignClient#getTvCertification] {"results":[{"descriptors":[],"iso_3166_1":"DE","rating":"12"},{"descriptors":[],"iso_3166_1":"KR","rating":"15"},{"descriptors":[],"iso_3166_1":"GB","rating":"12"},{"descriptors":[],"iso_3166_1":"BR","rating":"14"},{"descriptors":[],"iso_3166_1":"ES","rating":"13"},{"descriptors":[],"iso_3166_1":"US","rating":"TV-14"},{"descriptors":[],"iso_3166_1":"SG","rating":"NC16"}],"id":86031}
2023-11-15 16:56:57,789 DEBUG 3900 --- [https-jsse-nio-443-exec-6] c.n.i.global.openfeign.TmdbFeignClient   : [TmdbFeignClient#getTvCertification] <--- END HTTP (386-byte body)
2023-11-15 16:56:57,790  INFO 3900 --- [https-jsse-nio-443-exec-6] c.n.i.domain.tmdb.service.TmdbService    : TV 데이터 DB 저장 시작 : [86031] 닥터 스톤
2023-11-15 16:56:57,797  INFO 3900 --- [https-jsse-nio-443-exec-6] c.n.i.domain.tmdb.service.TmdbService    : TV 데이터 DB 저장 완료 : [86031] 닥터 스톤
2023-11-15 16:56:57,797  INFO 3900 --- [https-jsse-nio-443-exec-6] c.n.i.domain.tmdb.service.TmdbService    : SEASON 정보 DB 저장 시작
2023-11-15 16:56:57,824  INFO 3900 --- [https-jsse-nio-443-exec-6] c.n.i.domain.tmdb.service.TmdbService    : SEASON 정보 DB 저장 완료
2023-11-15 16:56:57,824  INFO 3900 --- [https-jsse-nio-443-exec-6] c.n.i.domain.tmdb.service.TmdbService    : 방송자 정보 DB 저장 시작
2023-11-15 16:56:57,841  INFO 3900 --- [https-jsse-nio-443-exec-6] c.n.i.domain.tmdb.service.TmdbService    : 방송자 정보 DB 저장 완료
2023-11-15 16:56:57,841  INFO 3900 --- [https-jsse-nio-443-exec-6] c.n.i.domain.tmdb.service.TmdbService    : Credits 정보 DB 저장 시작
2023-11-15 16:56:57,842  INFO 3900 --- [https-jsse-nio-443-exec-6] c.n.i.domain.tmdb.service.TmdbService    : Credits 정보 DB 저장 완료
2023-11-15 16:56:57,842  INFO 3900 --- [https-jsse-nio-443-exec-6] c.n.i.domain.tmdb.service.TmdbService    : TMDB API details 및 credits 정보 DB 저장 완료
2023-11-15 16:56:57,907 DEBUG 3900 --- [https-jsse-nio-443-exec-6] m.m.a.RequestResponseBodyMethodProcessor : Using 'application/json', given [*/*] and supported [application/json, application/*+json]
2023-11-15 16:56:57,907 DEBUG 3900 --- [https-jsse-nio-443-exec-6] m.m.a.RequestResponseBodyMethodProcessor : Writing [com.ncookie.imad.global.dto.response.ApiResponse@607d3f15]
2023-11-15 16:56:57,908 DEBUG 3900 --- [https-jsse-nio-443-exec-6] o.s.web.servlet.DispatcherServlet        : Completed 200 OK
2023-11-15 16:56:57,959  INFO 3900 --- [https-jsse-nio-443-exec-9] Spring Security Debugger                 : 

************************************************************

같은 작품 정보를 DB에 두 번 저장했을 때의 로그이다. 이쪽에서는 요청을 한 번만 날렸는데, response가 두 번 연달아 들어왔다(HTTP/1.1 200 OK (141ms), HTTP/1.1 200 OK (251ms)). 스프링에서는 이 둘을 별개의 응답으로 판단하고 각각 로직을 수행하여 DB에 저장했기 때문에 데이터가 중복으로 저장된 것이다.

원인은 크게 두 가지로 추측된다.

  1. 지금 프로젝트에서 외부 API 요청할 때 사용하는 OpenFeign 라이브러리 내부의 버그로 요청이 두 번 날라감
  2. TMDB API 서버가 응답을 두 번 보내줌

로그 상으로는 OpenFeign의 request가 한 번만 찍혀있기 때문에 2번 쪽에 무게가 실리지만, 확실한 것은 아니다. TMDB developer 커뮤니티 쪽에 질문글을 올려보려고 한다.

어느 쪽이 문제이던 내가 직접적으로 조치를 취할 수는 없다. 때문에 같은 문제가 발생하지 않도록 DB 저장 시 한번 더 중복 체크를 실시할 수 있도록 해야한다.