2026/03 26

Spring Boot JPA Auditing(@CreatedDate 등)로 생성/수정 시간 자동 기록하기

Spring Boot 3.x에서 JPA Auditing으로 createdAt/updatedAt을 자동 채우는 방법과 베이스 엔티티 설계, 운영에서 자주 겪는 함정을 정리합니다.도입 (문제 상황)엔티티를 저장할 때마다 createdAt, updatedAt을 매번 세팅하다 보면, 한두 군데는 꼭 빠지기 마련입니다. 특히 배치/관리자 기능/테스트 코드에서 누락되면 “왜 어떤 데이터는 시간이 비어 있지?” 같은 운영 이슈로 이어지기도 해요. 이럴 때 JPA Auditing을 쓰면 생성/수정 시간을 거의 자동화할 수 있습니다.핵심 개념 — Spring Boot JPA Auditing이 중요한 이유JPA Auditing은 엔티티의 “언제 생성/수정됐는지(그리고 누가 했는지)” 같은 메타 정보를 영속성 이벤트 시점에..

Spring Boot 2026.03.17

Spring Boot 페이징과 정렬 실전 가이드 (성능 함정: Slice vs Page, count 최적화, keyset pagination)

Spring Boot 3.x + Spring Data JPA에서 Pageable을 제대로 쓰는 방법과 Page/Slice 선택 기준, count 쿼리 최적화, keyset pagination(커서 페이징)까지 실전 관점으로 정리합니다.도입 (문제 상황)목록 API를 만들 때 Pageable만 붙이면 끝일 것 같지만, 운영에 올리면 갑자기 DB가 느려지거나 count 쿼리가 병목이 되는 경우가 많습니다. 특히 “페이지 수를 보여줘야 해서 Page로 했는데 응답이 느려요” 같은 상황을 자주 겪으실 거예요. 이번 글에서는 페이징/정렬을 “되는 코드”가 아니라 “성능까지 고려한 코드”로 만드는 기준을 잡아봅니다.핵심 개념: Spring Data JPA 페이징/정렬에서 진짜 중요한 것들1) Pageable은 편하..

Spring Boot 2026.03.17

Spring Boot JPA N+1 문제 원인과 해결 전략 (fetch join / EntityGraph / 배치 사이즈)

Spring Boot 3.x에서 JPA N+1 문제가 발생하는 조건을 정리하고, fetch join과 @EntityGraph로 해결하는 방법, 그리고 batch size로 보완하는 실무 전략을 예제 코드로 설명합니다.도입 (문제 상황)목록 API 하나 만들었을 뿐인데, 로컬에서는 빠르다가 데이터가 조금만 늘면 갑자기 DB 쿼리가 수십~수백 번 나가는 경험을 하실 때가 있습니다. 로그를 보면 “주 쿼리 1번 + 연관 엔티티 조회 쿼리 N번” 패턴이 반복되는데, 이게 대표적인 N+1 문제입니다.핵심 개념: N+1이 왜 생기고, 무엇을 선택해야 하나요?N+1은 “연관 로딩 전략”과 “조회 방식”이 맞물릴 때 발생합니다. 보통은 @ManyToOne(fetch = LAZY) / @OneToMany(fetch = ..

Spring Boot 2026.03.16

Spring Boot JPA 엔티티 설계 원칙(연관관계 포함) — 실무에서 덜 고생하는 기본기

Spring Boot 3.x 기준으로 JPA 엔티티를 설계할 때 꼭 지켜야 할 원칙(식별자 전략, 연관관계 방향, Lazy 기본, 엔티티 코드 규칙)을 예제 코드로 정리합니다.도입 (문제 상황)Spring Data JPA로 Repository는 금방 만들었는데, 엔티티 설계에서부터 막히는 경우가 많아요. 연관관계를 어디에 두어야 할지, LAZY로 두면 언제 터지고 EAGER로 두면 왜 느려지는지, 식별자는 어떤 전략이 안전한지 고민이 시작됩니다. 이 글에서는 “나중에 운영에서 덜 고생하는” 엔티티 설계 원칙을 기준으로 정리해 볼게요.핵심 개념 (Spring Boot JPA 엔티티 설계 원칙)1) 엔티티는 “DB 테이블”이 아니라 “도메인 모델”로 설계합니다엔티티는 단순 DTO가 아니라 상태와 규칙을 가진..

Spring Boot 2026.03.12

Spring Boot에서 Spring Data JPA 시작하기: Repository 인터페이스(CrudRepository/JpaRepository)와 쿼리 메서드, 페이징 기본

Spring Boot 3.x에서 Spring Data JPA Repository 인터페이스를 선택하고(CrudRepository/JpaRepository), 쿼리 메서드와 Pageable로 페이징을 빠르게 적용하는 실전 시작 가이드입니다.1) 도입 (문제 상황)JPA로 CRUD를 만들려고 보면, “EntityManager로 직접 다 짜야 하나요?” 같은 고민이 먼저 생깁니다. 또 목록 API를 만들 때마다 페이징/정렬을 매번 수동으로 처리하다 보면 코드가 금방 지저분해져요. 이럴 때 Spring Data JPA의 Repository 인터페이스를 제대로 잡아두면 시작 속도가 확 달라집니다.2) 핵심 개념 — Spring Data JPA Repository가 중요한 이유Spring Data JPA의 핵심은 ..

Spring Boot 2026.03.12

Spring Boot에서 @Transactional 제대로 쓰기(전파/읽기전용) — 프록시부터 실수까지

Spring Boot 3.x에서 @Transactional이 프록시로 동작하는 방식, readOnly의 실제 효과, 전파 옵션(Propagation) 선택 기준과 현업에서 자주 하는 실수를 코드로 정리합니다.도입 (문제 상황)서비스 메서드에 @Transactional을 붙였는데도 “왜 롤백이 안 되지?” 혹은 “readOnly로 했는데도 업데이트 쿼리가 나가네?” 같은 상황을 한 번쯤 겪으셨을 거예요. 특히 계층형 구조(Controller/Service/Repository)를 잘 나눠도, 트랜잭션 경계가 어긋나면 데이터 정합성이 쉽게 깨집니다.이번 글에서는 @Transactional이 **어떻게 동작하는지(프록시)**부터 readOnly의 진짜 의미, 전파 옵션 선택, 자주 하는 실수를 실무 관점으로 정..

Spring Boot 2026.03.11

Spring Boot 계층형 구조(Controller/Service/Repository) 잘 나누는 법 — 책임 분리와 DTO/엔티티 경계

Spring Boot 3에서 Controller/Service/Repository를 깔끔하게 분리하는 기준과 DTO/엔티티 경계, 서비스 레이어 규칙을 실무 관점에서 정리합니다.도입 (문제 상황)기능이 몇 개 없을 때는 Controller에서 Repository를 바로 호출해도 잘 돌아가지만, 요구사항이 늘어나면 “이 로직은 어디에 둬야 하지?”가 빠르게 문제가 됩니다. 특히 DTO와 엔티티를 섞어 쓰기 시작하면, 작은 변경에도 여러 계층이 같이 흔들리면서 유지보수가 어려워져요.핵심 개념: Spring Boot 레이어드 아키텍처에서 “경계”를 지키는 기준Controller/Service/Repository를 나누는 목적은 “코드를 예쁘게 분류”하는 게 아니라 변경의 파급 범위를 줄이는 것입니다. 각 계층..

Spring Boot 2026.03.11

Spring Boot 검증(Validation)과 에러 응답 표준화: @Valid부터 @ControllerAdvice까지

Spring Boot 3에서 @Valid, BindingResult, @ControllerAdvice로 입력 검증을 적용하고, 공통 에러 응답 포맷을 설계해 일관된 API를 만드는 방법을 정리합니다.도입 (문제 상황)API를 만들다 보면 “필수값이 빠졌는데 500이 떨어져요”, “어떤 API는 errors 배열이고 어떤 API는 message 하나예요” 같은 상황을 자주 만나게 됩니다. 검증은 넣었는데 응답 포맷이 제각각이라 프런트/모바일에서 예외 처리가 더 어려워지기도 해요. 이 글에서는 Spring Boot 3 기준으로 검증과 에러 응답을 한 번에 정리해 보겠습니다.핵심 개념: Spring Boot Validation이 중요한 이유와 표준화 포인트검증(Validation)은 단순히 “값이 비었는지”를..

Spring Boot 2026.03.10

Spring Boot 요청/응답 바인딩(@RequestBody, @ModelAttribute) 실전 가이드

Spring Boot 3에서 폼/쿼리/JSON 바인딩 차이와 Jackson 설정 포인트, null 처리 전략을 실전 코드로 정리합니다.도입 (문제 상황)API를 만들다 보면 “같은 DTO인데 왜 어떤 요청은 바인딩이 되고, 어떤 요청은 400이 나지?” 같은 상황을 자주 만나게 됩니다. 특히 폼 전송/쿼리스트링은 잘 되는데 JSON은 갑자기 실패하거나, null 처리 때문에 업데이트 API가 의도치 않게 값을 지워버리는 일도 생깁니다. 이번 글에서는 Spring Boot에서 요청/응답 바인딩을 실전 관점으로 정리해 봅니다.핵심 개념: Spring Boot 바인딩이 갈리는 지점 (@RequestBody vs @ModelAttribute)Spring MVC에서 바인딩은 크게 두 갈래로 나뉩니다.@ModelA..

Spring Boot 2026.03.10

Spring Boot에서 @Controller vs @RestController 제대로 구분하기 (View 렌더링과 JSON 응답 기준)

Spring Boot 3에서 @Controller와 @RestController의 차이를 View 렌더링/JSON 응답 관점에서 정리하고, ResponseEntity 사용 기준과 실무 컨벤션까지 예제로 확인합니다.도입 (문제 상황)페이지는 잘 떠야 하는데 갑자기 JSON이 내려오거나, 반대로 API를 만들었는데 뷰 이름을 찾다가 404가 나는 경험을 해 보셨을 거예요. 특히 “컨트롤러는 그냥 컨트롤러 아닌가?”라고 생각하고 @Controller와 @RestController를 섞어 쓰면, 작은 차이가 운영에서 큰 장애로 번지기도 합니다.핵심 개념: Spring Boot에서 @Controller와 @RestController 차이가 중요한 이유결론부터 말하면, 두 애노테이션의 차이는 “반환값을 무엇으로 해..

Spring Boot 2026.03.09