[트러블 슈팅] ⚠️ Spring Boot LocalDateTime 변환 에러 해결법 (@JsonFormat vs @DateTimeFormat)
·
프로젝트 트러블 슈팅 및 몰랐던점 정리/CommunityAPI
Spring Boot로 REST API를 개발하다 보면 LocalDateTime 객체를 JSON으로 변환하는 과정에서 오류를 겪곤한다. 특히 Jackson(ObjectMapper)을 사용할 때 별도 설정 없이 LocalDateTime을 직렬화하려고 하면 예외가 발생한다.  문제 상황게시글 등록 API를 호출하면서 LocalDateTime.now()로 생성 날짜를 지정한 후 DB에 저장하려 했지만, 아래와 같은 에러가 발생했다.2025-03-02T00:09:54.324+09:00 ERROR 73471 --- [free_community] [nio-8080-exec-1] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dis..
[트러블 슈팅] ⚠️ @RequestBody로 MultipartFile을 받을 수 없는 이유와 해결법(@RequestPart)
·
프로젝트 트러블 슈팅 및 몰랐던점 정리/CommunityAPI
문제 상황새로운 게시글을 등록할 때, 다음과 같이 DTO로 데이터를 받고 있다.public class PostCreateRequest { private String categoryName; private String title; private String content; private List images;}이때 컨트롤러에서 해당 DTO를 @RequestBody로 받아 처리하는데, JSON 형식의 데이터만 변환 가능하기 때문에 바이너리 데이터인 MultipartFile은 JSON으로 표현할 수 없어 에러가 발생한다.문제 원인 분석Spring의 @RequestBody는 JSON 형식의 요청 본문만 처리한다.• JSON은 텍스트 기반 데이터인데, 파일(MultipartFile)은 바이너..
[학습 포인트] 💡 JPA에서 update 시 @Modifying 애노테이션이 필요한 이유
·
프로젝트 트러블 슈팅 및 몰랐던점 정리/CommunityAPI
JPA의 기본 동작부터 알아보자!JPA에서 사용하는 @Query 애노테이션은 기본적으로 데이터를 **조회(SELECT)**할 때 사용된다. 그래서 UPDATE나 DELETE처럼 데이터를 변경할 때는 JPA에게 추가적으로 알려줘야 한다. 이때 JPA가 헷갈리지 않도록 명확히 알려주는 방법이 바로 @Modifying 애노테이션이다! 🚨 @Modifying이 꼭 필요한 이유 3가지① 변경 쿼리임을 명확히 알려주기 • JPA는 기본적으로 모든 @Query를 SELECT 쿼리라고 생각한다.• 그런데 UPDATE나 DELETE 쿼리는 데이터베이스에서 실제로 데이터를 변경하는 쿼리라서, JPA의 1차 캐시(영속성 컨텍스트)와 충돌이 생기며 이로인한 동기화 과정에서 동기화가 제대로 되지 않아 데이터의 정합성이 깨지는..
[트러블 슈팅] 포트 분리로 인한 채팅 불가 feat Redis PubSub
·
프로젝트 이슈 및 몰랐던점 정리/PlistAPI
이번 프로젝트를 진행하면서 채팅 + 비디오 동기화 프로젝트를 진행했었다.여기서 채팅과 비디오 동기화 문제를 해결하기 위해서 WebSocket과 STOMP를 이용해서 클라이언트로 부터 오는 데이터를 서버쪽에서 가공 후 발행하면 구독하고 있는 주소로 데이터를 보내는 형식으로 로직을 작성했는데, 해당 방식의 문제점은 로드 밸런서를 구성한 환경에서는 8080포트 이용자와 8081포트의 이용자는 서로 메시지를 주고 받을 수 없는 환경이라는 것이다. Nginx가 앞에서 모든 요청에 대해서 Round Robin 알고리즘으로 무작위로 8080포트와 8081포트로 요청을 분산시키는데 이 때 만약에 사용자1은 8080포트로 연결되고, 사용자2는 8081포트로 연결되었을 때 사용자1과 사용자2는 서로 채팅을 주고받을 수 없..
[트러블 슈팅] GitHub Actions GradleWrapperMain 에러
·
프로젝트 이슈 및 몰랐던점 정리/PlistAPI
어떤 에러인가소스코드를 수정하고 Gradle을 Build하는 과정에서 어느 순간 부터 에러가 지속적으로 났었다. 에러명은 ClassNotFoundException GradleWrapperMain이라는 클래스를 찾을 수 없단다... 처음보는 종류의 에러였다.저게 대체 뭔 클래스인데...??? CICD 스크립트를 보면 - name: Build with Gradle run: | echo ${{ secrets.APPLICATION_SECRET }} | base64 --decode > ./src/main/resources/application-secret.properties echo ${{ secrets.APPLICATION_PROD }} | base64 --decod..
[배포] Nginx + Certbot으로 https 연결하기
·
프로젝트 이슈 및 몰랐던점 정리/PlistAPI
이번 팀프로젝트를 진행하면서 서버쪽 관리와 Nginx를 사용한 무중단 배포 및 Https 연결을 맡았다.개인프로젝트를 진행하면서 코드와 Swagger 작업만 마친채로 항상 그쳤었는데 이번에 서버 관리쪽을 맡으면서 정말 많은 것을 깨달았고, 이제 혼자서도 배포를 할 수 있을 정도로 Linux를 활용한 기본적인 명령어도 숙지할 수 있는, 한단계 업그레이드 할 수 있는 좋은 기회였다. 이번 팀프로젝트를 진행하면서 배운 기술들과 이슈 관련해서 천천히 정리해서 포스팅 해보려 한다.Nginx이번에 팀프로젝트를 하면서 Nginx를 적용한 이유는 무중단 배포를 경험해보고 싶었던 이유가 가장 크기도 하다. Nginx의 가장 큰 특징중 하나인 리버스 프록시라는 특징을 이용하면 데이터를 요청하는 클라이언트는 백엔드 서버가 ..
[트러블 슈팅] Spring HATEOAS - 단일 리소스에 대한 API 엔드 포인트 제공
·
프로젝트 트러블 슈팅 및 몰랐던점 정리/CommunityAPI
HATEOASHATEOAS는 Hypermedia as the Engine of Application State의 약자로, RESTful API에서 클라이언트가 서버와 상호작용하는 방식 중 하나이다. API 응답에 대해 어떠한 행동에 대한 API 엔드포인트 링크를 포함시켜 클라이언트가 API의 다양한 행동을 동적으로 쉽게 탐색할 수 있는 방식이다. 즉 서버가 클라이언트에게 필요한 정보를 제공할 때, 그 정보와 함께 다음에 클라이언트가 어떤 행동을 할 수 있는지에 대한 API엔드 포인트를 명시해 주는 방식이다. 예를 들어 사용자가 로그인한 경우 아래 JSON과 같은 형식을 보내줌으로써 서버가 API의 변화에 유연하게 작동할 수 있다. 새로운 링크를 통해 적응할 수 있기 때문에 서버와 클라이언트의 결합도를 ..
[트러블 슈팅] JPA - LazyInitializationException과 N+1
·
프로젝트 트러블 슈팅 및 몰랐던점 정리/CommunityAPI
LazyLoding의 기본 동작LazyInitializationException은 영속성 컨텍스트가 종료된 상태에서 LAZY 전략을 사용하려고 할 때 발생한다. @OneToMany 혹은 @ManyToMany (xToMany) 연관관계 매핑 시 기본 전략은 LAZY 전략이다. 이는 실제 데이터에 접근할 때 까지 연관관계의 매핑된 데이터를 로드하지 않는다. 이로 인해 연관관계로 매핑된 엔티티에 대해서 초기화 되지 않은 프록시 객체로 유지되다가 연관관계로 매핑된 엔티티 필드(데이터가 실제로 필요할 때)에 접근하면 데이터베이스에서 실제 데이터를 조회하려고 시도한다. 이 때 JPA는 영속성 컨텍스트가 활성화된 상태에서 프록시를 초기화하고 데이터베이스와 상호작용을 하게되는데, Spring 에서는 트랜잭션의 범위가..
cheolhyeon
'프로젝트 이슈 및 몰랐던점 정리' 카테고리의 글 목록 (2 Page)