Backend/Java 29

MapStruct와 ObjectMapper, 언제 어떤 걸 써야 할까?

DTO ↔ Entity 변환, 여러분은 어떻게 처리하고 계신가요?🤔 많은 개발자들이 처음에는 직접 생성자나 Builder를 사용해서 매핑합니다.필드가 몇 개 없을 때는 괜찮지만, 점점 DTO/Entity 구조가 복잡해지고, 중복 코드가 많아지면서 유지보수가 어려워지는 것 같습니다.이럴 때 보통 두 가지 대안이 있습니다.ObjectMapper: 빠르고 간편하게 쓸 수 있는 JSON 매핑 도구MapStruct: 컴파일 타임에 타입 안전하게 매핑 코드를 생성해 주는 프레임워크이번 글에서는 두 방식의 차이점과 실무에서 어떤 상황에 어떤 방식을 선택하는 것이 좋은지 정리해 보겠습니다. ObjectMapper란?ObjectMapper는 Jackson 라이브러리에서 제공하는 객체-JSON 변환 도구입니다.(사실 ..

Backend/Java 2025.07.23

[Java] Collectors.toList() vs Stream.toList()

Java에서 Stream API를 사용할 때 Collectors.toList()는 오랫동안 익숙하게 사용해온 방식이었습니다.그런데 최근 IntelliJ에서 Stream.toList() 사용을 권장하는 안내 메시지를 보고 궁금증이 생겼습니다. 🤔이번 글에서는 두 방식의 차이점과 언제 어떤 걸 선택해야 하는지 명확히 정리해보겠습니다. Collectors.toList() → 변경 가능한 리스트 (mutable)List list = Stream.of("A", "B", "C").collect(Collectors.toList());list.add("D"); // 가능! 리스트에 값 추가됨Collectors.toList()는 내부적으로 new ArrayList()를 사용해 리스트를 생성합니다.그래서 리스트에 값..

Backend/Java 2025.07.09

OutOfMemory: IntelliJ IDEA로 Heap Dump(.hprof) 분석하기

주니어 개발자라면 한 번쯤 마주할 수 있는(?) OutOfMemoryError (OOM)저도 JVM 기반 백엔드 서비스를 운영하다가 실제로 OOM을 겪게 되었고, 이를 계기로 `.hprof` 파일을 분석해 보게 되었습니다.(참고로 이번 OOM은 메모리 사용량 자체보다는 설정 이슈였지만, 메모리 문제에 대비한 분석 경험으로 의미 있었기에 글로 정리합니다!) 📦 .hprof 열기 (IntelliJ Ultimate 기준).hprof 파일은 JVM에서 OOM 발생 시 생성되는 힙 메모리 스냅샷입니다.IntelliJ Ultimate에서는 아래와 같이 쉽게 열 수 있어요! 1. .hprof 파일을 IntelliJ로 드래그하거나 File → Open으로 열어줍니다. 2. 파일을 열어주면 자동으로 Heap Dump..

Backend/Java 2025.05.28

[Java] Map.getOrDefault()가 예외를 던진다고?

Map.getOrDefault()를 사용하다가 Exception을 만난 경험이 있다면, 이 글이 도움이 될 수 있습니다.많은 사람들이 "getOrDefault는 키가 없을 때만 기본값을 사용한다"라고 생각하지만, 실제 동작은 다릅니다.이 글에서는 getOrDefault()의 진짜 동작 방식을 알아보고, 안전한 대안까지 정리해 보겠습니다. 👩🏻‍💻 예상 못한 예외, 어디서부터 잘못된 걸까?다음 코드에서 NumberFormatException이 발생했습니다.Long no = noMap.getOrDefault(update.getNo(), Long.valueOf(update.getNo()));에러 메시지는 아래와 같았습니다.java.lang.NumberFormatException: For input str..

Backend/Java 2025.04.16

JDK 23: 자바 핵심 변경점 정리

JDK 23은 자바 언어와 플랫폼의 최신 개선 사항을 포함하여 개발자 생산성과 애플리케이션 성능을 향상시키는 다양한 기능을 도입했습니다. 주요 변경 사항에 대해 알아보겠습니다.👀  1. 프리미티브 타입에 대한 패턴 매칭 및 switch 문 확장 (JEP 455)1-1. 패턴 매칭의 확장기존에는 instanceof 연산자가 참조 타입에서만 동작했지만, JDK 23부터는 프리미티브 타입에서도 사용할 수 있습니다.int value = 10;if (value instanceof int i && i > 5) { System.out.println("Value는 5보다 큰 정수입니다: " + i);}위 코드는 instanceof 연산자로 프리미티브 타입 int를 확인하고, 조건을 추가적으로 결합하여 안전하고 ..

Backend/Java 2025.01.15

Jackson 커스텀 어노테이션: @JacksonAnnotationsInside

Jackson 관련하여 공통적인 코드를 분리하기 위해 커스텀 어노테이션을 만들어 사용하기로 결정했습니다.그 과정에서 Jackson이 커스텀 어노테이션을 인식하도록 하기 위해 @JacksonAnnotationsInside라는 어노테이션이 필요하다는 사실을 알게 되었고, 이를 정리해보았습니다. 👀 @JacksonAnnotationsInside란 무엇인가?`@JacksonAnnotationsInside`는 Jackson 라이브러리에서 제공하는 메타 어노테이션으로, 커스텀 어노테이션이 Jackson의 어노테이션처럼 동작하도록 정의할 때 사용됩니다. 즉, 이 어노테이션이 없으면 Jackson이 커스텀 어노테이션을 인식하지 못합니다.왜 필요한가?기본적으로 Jackson은 자신이 제공하는 어노테이션(@JsonNam..

Backend/Java 2024.12.21

[Java] JPA에서 발생하는 N+1 이슈: 원인부터 해결까지

JPA를 처음 사용할 때 많은 개발자들이 부딪히는 문제 중 하나가 바로 N+1 이슈입니다. 이번 글에서는 JPA 환경에서 N+1 이슈가 발생하는 원인을 알아보고, 이를 해결할 수 있는 방법을 정리해보겠습니다.   N+1 이슈란?N+1 이슈는 1개의 메인 쿼리로 데이터를 가져오려 했지만, 추가로 N개의 쿼리가 실행되는 문제를 뜻합니다.다음은 간단한 예제를 통해 이를 이해해보겠습니다. 엔티티 구조Member와 Order 간에 일대다 관계가 있다고 가정합니다.@Entitypublic class Member { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String name; @One..

Backend/Java 2024.11.27

Java의 Reflection 사용법과 주의점

Java에서 Reflection은 클래스나 메서드, 필드 같은 객체 정보를 "런타임"에 읽고 수정할 수 있는 도구입니다. 간단히 말해, 코드가 실행되는 도중에 "클래스의 내부를 엿보거나 조작"할 수 있게 해주는 강력한 기능입니다. 이 글에서는 Reflection이 무엇인지, 어떻게 사용하는지, 그리고 주의해야 할 점을 하나씩 살펴보겠습니다! 🚀 Reflection이란?Reflection은 말 그대로 반사처럼 프로그램이 자신을 들여다보고 조작할 수 있게 하는 기능입니다.어디에 쓰일까요?라이브러리/프레임워크: Spring 같은 프레임워크에서 빈(bean)을 생성하거나 주입할 때동적 동작: 컴파일 시점에 알 수 없는 클래스의 메서드나 필드를 실행해야 할 때테스트: 테스트 코드에서 private 메서드나 필드..

Backend/Java 2024.11.24

[Java] 빌더 패턴

자바에서 객체를 생성할 때 `new` 키워드를 사용한 생성자 호출 외에도 빌더 패턴을 활용하면 더 가독성 있고 유연한 코드를 작성할 수 있습니다. 특히, 필드가 많은 객체나 옵션이 다양한 경우 빌더 패턴은 매우 유용합니다. 이번 글에서는 빌더 메서드의 기본 개념, 장점, 실무 활용법을 정리하겠습니다! 👩🏻‍💻 빌더 패턴이란?빌더 패턴은 복잡한 객체의 생성 과정을 단순화하고, 가독성과 유지보수성을 높이기 위해 고안된 디자인 패턴입니다. 기본 빌더 패턴 코드 예제public class User { private final String name; private final int age; private final String email; // Builder 클래스 public s..

Backend/Java 2024.11.23

JPA FetchType.EAGER와 LAZY의 차이 알아보기

JPA를 사용할 때 @OneToMany, @ManyToOne 등 연관 관계를 매핑할 때 종종 등장하는 옵션이 있습니다. 바로 FetchType.EAGER와 FetchType.LAZY입니다. 이 두 옵션은 연관된 엔티티 데이터를 언제 로딩할지를 결정하며, 올바르게 설정하지 않으면 성능 문제를 일으킬 수 있습니다. 이번 글에서는 두 FetchType의 차이와 실무에서의 사용법을 다뤄보겠습니다. FetchType이란?FetchType은 JPA에서 엔티티의 연관된 데이터를 가져오는 방식을 정의합니다.기본적으로 JPA는 두 가지 FetchType을 제공합니다:EAGER (즉시 로딩)LAZY (지연 로딩)FetchType.EAGER (즉시 로딩)즉시 로딩은 엔티티를 조회할 때 연관된 엔티티 데이터도 즉시 가져옵니다..

Backend/Java 2024.11.22