Querydsl - Cannot invoke "com.querydsl.core.types.Expressions.accept(com.querydsl.core.types.Visitor, Object)" because "arg" is null" 원인과 해결 방법
·
나의 에러 일지
Cannot invoke "com.querydsl.core.types.Expressions.accept(com.querydsl.core.types.Visitor, Object)" because "arg" is nullQuerydsl에서 @QueryProjection을 사용해 DTO를 조회하는 과정에서 발생한 예외이다. 원인Querydsl에서 DTO를 @QueryProjection으로 조회할 때, select 절에 일부 필드를 null로 반환하고자 직접 null을 명시하면 아래와 같은 예외가 발생할 수 있다. 예외가 발생한 코드는 아래와 같다.import com.querydsl.core.types.dsl.Expressions;import com.querydsl.core.types.Projections;QM..
Spring - ContentCachingRequestWrapper에서 getContentAsByteArray가 빈 값을 반환하는 이유와 해결 방법
·
나의 에러 일지
배경실제 프로젝트에서 Request Body로부터 traceId를 전달받아 이를 저장하고, 이후 로깅이나 트레이싱 등에 활용해야 하는 요구사항이 있었다. 이를 위해 Spring에서 제공하는 ContentCachingRequestWrapper를 사용하기로 했다. ContentCachingRequestWrapper는 원래 InputStream, Reader, 혹은 @RequestBody로 Request Body를 한번 읽고 나면 다시 읽을 수 없다는 한계를 깔끔하게 해결해 주는 유용한 클래스이다. 덕분에 traceId 같은 중요한 데이터를 여러 계층에서 반복적으로 로깅하거나 재사용할 수 있다. 그런데 실제로 적용하는 과정에서, ContentCachingRequestWrapper로 감쌌음에도 불구하고 Requ..
Spring - 딸깍으로 쉽게 Request 로그 남기기(CommonsRequestLoggingFilter)
·
Spring
배경애플리케이션을 운영하다 보면, 클라이언트의 요청이 어떻게 들어오는지, 어떤 데이터가 전달되는지 로그를 남겨둬야 할 때가 있다. 특히, 복잡한 API를 개발하거나, 에러 대응 및 디버깅이 필요할 때 요청 정보를 간단하게 로깅할 수 있다면 작업 효율이 크게 올라갈 것이다. 현재 진행중인 프로젝트에서 Request에 대한 로깅이 필요했고, Spring에서 제공하는 CommonsRequestLoggingFilter라는 도구를 알게되었다. 복잡한 설정 없이 손쉽게 Request 정보를 로깅할 수 있다는 장점이 있다. 이 글에서는 CommonsRequestLoggingFilter를 이용해 딸깍 한 번으로 쉽게 Request 요청을 로그로 남길 수 있는지 공유하려고 한다. 코드는 아래 링크에서 확인할 수 있다. ..
소프트웨어 버전 관리
·
etc
{Major}.{Minor}.{PATCH} 구조 Major 버전: 이전 버전과 호환되지 않는 API 변경 시 증가 Minor 버전: 하위 호환 가능한 새로운 기능 추가 시 증가 Patch 버전: 하위 호환 가능한 버그 수정 시 증가 버전 증가 규칙 각 버전 번호는 음수가 아닌 정수여야 함 상위 버전이 증가하면 하위 버전은 0으로 리셋 (예: 1.9.0 → 1.10.0 → 2.0.0) 버전 배포 후 해당 버전의 내용은 절대 변경 금지. 변경사항이 있다면 반드시 새로운 버전으로 배포
Spring - Spring Data Envers로 엔티티 변경 이력을 쉽게 관리해보기
·
Spring
배경사이드 프로젝트나 실제 서비스에서 데이터 변경 이력 관리가 필요할 때가 많다. “누가, 언제, 무엇을, 어떻게 바꿨는지” 추적이 필요하다면, Spring Data Envers가 딱이다. 이번 글에서는 Spring Data Envers를 실제로 적용하는 방법을, 내가 직접 해보면서 겪은 시행착오와 함께 정리해본다. Envers란?Hibernate Envers는 JPA 엔티티의 변경 이력을 자동으로 관리해준다. Spring Data Envers는 이를 Spring Data JPA와 자연스럽게 통합해주기 때문에, 기존 Repository 패턴을 그대로 쓰면서도 이력 관리가 가능하다 프로젝트에 Envers 적용하기의존성 추가build.gradle에 아래 의존성을 추가한다.implementation 'org...
Docker - standard_init_linux.go:xxx: exec user process caused "exec format error“ 원인과 해결 방법
·
나의 에러 일지
배경기존에는 Dockerfile에서 Java 애플리케이션을 실행할 때 ENTRYPOINT에 모든 JVM 옵션과 실행 명령어를 길게 나열해서 작성했었다. 하지만 JVM 옵션이 많아지고 환경별로 다른 설정이 필요해지면서 관리가 어려워졌다. 그래서 별도의 쉘 스크립트 파일에서 이런 복잡한 실행 로직을 관리할 수 있도록 entrypoint.sh를 만들게 되었다. entrypoint.sh를 추가하여 Docker 컨테이너를 실행하자 entrypoint.sh에서 예상치 못한 format 에러가 발생했다.standard_init_linux.go:xxx: exec user process caused "exec format error“ 개발 환경DockerPortainerLinuxJava 17Spring Boot 3.4..
HTTP - 프록시 환경에서 실제 클라이언트 IP 찾기 (X-Forwarded-For, X-Real-IP)
·
Network
배경새로운 프로젝트에서 화이트리스트 IP 검증 로직(IP 기반 접근 제한)을 구현하게 되었다. 처음에는 단순하게 request.getRemoteAddr()를 사용하면 될 줄 알았는데, 실제 운영 환경에서는 중간에 프록시를 거치다보니 실제 클라이언트 IP가 아닌 프록시 IP가 조회되는 문제가 있었다. 이 문제를 해결하기 위해 알게된 X-Forwarded-For와 X-Real-IP에 대해 알아보자 문제 상황웹 애플리케이션을 개발하다 보면 클라이언트의 실제 IP 주소가 필요한 경우가 많다. 특히 보안 정책, 접근 제어, 로깅 및 분석 등의 목적으로 사용된다. 하지만 실제 운영을 위한 웹 아키텍처에서는 클라이언트와 서버 사이에 다양한 중간 계층들이 존재한다. 로드 밸런서, 리버스 프록시, CDN 등을 거치면서 ..
JPA - Entity 필드 작성 순서 Best Practice
·
JPA
배경프로젝트에서 여러 개발자가 Entity를 작성하다 보니 각자 다른 순서로 필드를 배치하는 경우가 많았다. 코드 리뷰를 하면서 일관성 있는 Entity 작성 규칙이 필요하다고 느꼈고, 특히 데이터 마이그레이션 작업이나 테이블 비교 시에도 필드 순서가 중요하다는 것을 깨달았다. 그래서 팀 내에서 사용할 수 있는 Entity 필드 작성 순서 가이드를 정리해보게 되었다. 혹시 더 괜찮은 구조가 있다면 댓글에 남겨주세요! Entity 필드 작성 순서식별자 > 기본 속성 > 임베디드 값 객체 > 연관관계 > Audit 필드1. 식별자순서: 기본 키(Primary Key) > 비즈니스 식별자(Business Key)기본키는 항상 가장 위에 작성한다.상품코드, 주문번호와 같이 비즈니스에서 사용하는 고유 식별자를 두..
Spring Data JPA - 낙관적 락, 비관적 락으로 동시성 제어해보기 (+ 테스트)
·
JPA
개요동시성 문제는 실무에서 자주 만난다. 이직 후 처음으로 진행하는 프로젝트에서 직접 채번을 해주는 로직을 구현해야 했는데, 테스트 중 동시성 문제가 발생해 비관적 락을 통해 동시성 제어를 해야 했다. 이 밖에도 재고 관리나 주문 시스템에서 여러 사용자가 동시에 같은 데이터를 건드릴 때 동시성 문제가 많이 발생한다. 이번에 Spring Data JPA를 통해 직접 코드로 구현해보면서 동시성 문제와 제어 방법을 이해해보자 아래 링크에서 코드를 확인할 수 있다. practice-java-spring/spring-concurrency at master · chanbinme/practice-java-springContribute to chanbinme/practice-java-spring development ..
Chrome(크롬) - ERR_UNSAFE_PORT 원인과 해결방법
·
나의 에러 일지
회사에 이직한 첫날, 신규 입사자 가이드에 따라 개발 환경을 세팅하다가 예상치 못한 에러를 만났다. 바로 ERR_UNSAFE_PORT. 지금 다니는 회사는 보안을 위해 내부망을 사용한다. 내부망 특성상 특정 포트로만 접속해야 했는데, 하필이면 그 포트가 크롬에서 "안전하지 않은 포트"로 분류되어 있었다. 다시 이 에러를 만났을 때 당황하지 않고 해결할 수 있도록, 경험을 정리해본다. 문제크롬에서 특정 포트(예: 6000, 6666 등)로 접속 시 아래와 같은 에러 메시지가 뜬다.www.naver.com:6000으로 접속하면 아래 이미지처럼 ERR_UNSAFE_PORT를 볼 수 있다. 원인크롬(및 일부 브라우저)은 보안상의 이유로 몇몇 포트로의 접근을 기본적으로 차단한다.해커들이 알려진 포트를 통해 공격을..
Cold Bean
'분류 전체보기' 카테고리의 글 목록