| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | ||||||
| 2 | 3 | 4 | 5 | 6 | 7 | 8 |
| 9 | 10 | 11 | 12 | 13 | 14 | 15 |
| 16 | 17 | 18 | 19 | 20 | 21 | 22 |
| 23 | 24 | 25 | 26 | 27 | 28 | 29 |
| 30 |
- 일급 객체
- synchronized
- spring security
- factory
- lombok
- builder
- nestjs
- 일급 컬렉션
- java
- Volatile
- OAuth 2.0
- middleware
- Google OAuth
- Spring
- Dependency Injection
- Today
- Total
목록전체 글 (191)
HJW's IT Blog
1. 엔티티 리스트를 조회했는데 프록시가 반환되었다JPA 를 다루며 쿼리 최적화를 위해 디버거와 로그를 통해 분석중 이었다. 그때, `Channel` 리스트를 조회해야 하는 쿼리의 반환값이 이해하기 힘들었다. 4개는 실제 객체, 2개는 프록시 객채였던 것이다. `Lazy Loading` 으로 불러온 객체들도 아닌, SimpleJpaRepository 의 findByIdIn 을 사용해 불러온 객체들 중 프록시가 포함되어 있다는 것이 이해가 되질 않았다. 아래는 이 현상을 분석하기 위해 Hibernate ORM 공식 문서와, 1차 캐시를 뜯어보며 분석해본 결과이다. 2. 세션과 영속성 컨텍스트 [공식문서]2.9.2. Natural Id APIAs stated before, Hibernate provides..
0. N + 1 이란Spring Data JPA 에서 연관관계가 있는 엔티티를 조회할 때, Lazy Loading 을 활용하여, 실제 데이터가 필요한 시점까지 연관 엔티티의 조회를 미룰 수 있다. 이는 양날의 검과 같다. 최적화를 하는 동시에 성능에 지대한 영향을 미칠 수 있다. 단편적인 예시가 바로 N + 1 문제이다. 한번의 부모 엔티티 조회 후, 각 자식 엔티티를 개별적으로 조회하는 비효율적인 쿼리 실행 문제를 두고 부르는 말이다. @Entitypublic class User { @Id @GeneratedValue private Long id; private String name; @OneToMany(mappedBy = "user", fetch = FetchType.LAZY) ..
0. Hibernate 프록시 객체본 글로 넘어가기전 간략하게 나마 Proxy 객체에 대해 짚고 넘어가겠다.JPA 의 엔티티 간에 연관 관계가 있을때, fetch = FetchType.LAZY 가 설정되어 있다면, Hibernate 는 DB에 실제 쿼리를 날리는 대신 임시 프록시 객체를 반환한다. 이로 인해, Hibernate 는 데이터가 실제로 필요한 순간까지 SQL 을 실행하지 않을 수 있다.Member member = em.getReference(Member.class, 1L); 이와 같이 getReference() 를 활용하면, 실제 클래스가 아닌 프록시 클래스를 조회할 수 있다. 1. 1:1 관계와 프록시 동작 분석@Entity public class Member { @Id ..
0. 들어가며JPA 의 entity 사이에 연관관계를 올바르게 설정하는것은 매우 중요하다. 데이터 무결성, 성능, 유지보수성 측면 모두에서 영향을 끼칠 수 있는것이 어떻게 연관 관계를 설정하는가 이다. 이번 글에서는, 연관관계의 주인 개념을 명확하게 짚고 넘어가겠다. 1. 연관관계란 무엇인가1.1 객체 지향 모델링 관점에서의 영향관계객체 지향 프로그래밍에서 연관관계는 하나의 객체가 다른 객체를 참조하거나 포함하는 구조를 의미한다. 즉, 객체간의 상호작용을 모델링할 수 있고, 현실의 개념을 더욱 직관적으로 표현할 수 있다. 예를 들어 User 와 Order 이 있다고 가정하자. User 는 여러 Order를 가질 수 있으며, Order 는 한명의 User 를 가진다. 이러한 관계를 어떻게 표현하고 설계할 ..
0. 들어가며JPA(Java Persistence API)는 Java 애플리케이션에서 데이터베이스와의 상호작용을 단순화하는 ORM(Object-Relational Mapping) 기술이다. 그중 EntityManager는 엔티티를 관리하고 데이터베이스의 CRUD 작업을 수행하는 핵심 객체이다. 이 글에서는 EntityManager의 역할과 특징, 그리고 영속성 컨텍스트의 동작 방식에 대해 다뤄보겠다.1. EntityManager 란?JPA 에서 Entity 를 관리하는 객체로, 데이터베이스의 CRUD 작업을 수행하는 역할을 한다. 다음과 같은 주요 기능을 수행한다.1.1 핵심 기능EntityManager 는 Entity 의 생명 주기를 관리한다.영속화 (Persist) : 엔티티 객체를 DB에 저장조회 ..
0. 들어가며 JPA 를 사용하며 SQL문을 보기 위해 보통 applicaion.yml 의 spring.jpa.show-sql = true 설정을 쓸 것이다. 하지만.. 너무 가독성이 떨어진다. 디버깅 하기도 어렵고 어떤 쿼리가 발생하는지 읽기도 힘들다. 이번 포스팅에선 이러한 Hibernate 가 자동으로 찍어주는 쿼리 대신 P6Spy 라이브러리를 이용한 쿼리 커스터마이징에 대해 다루겠다. 1. 적용 전Hibernate: select user0_.id as id1_0_, user0_.age as age2_0_, user0_.name as name3_0_ from user user0_ where user0_.name=? 정말 읽기 힘들고 가독성이 떨어지는 코드가 발생한다. 물론, format-sql = ..
0. MapStruct 란 무엇인가?0.0 DTO 도메인 엔티티 변환 Java 코드를 작성하다 보면 DTO와 도메인 엔티티 간의 변환 작업이 빈번하게 발생한다. 특히, 계층적 구조를 가진 애플리케이션에서는 Controller - Service - Repository를 거치며 DTO와 엔티티를 서로 변환하는 일이 반복된다. 이를 수작업으로 작성할 경우,필드가 추가되거나 변경될 때마다 수동으로 코드를 수정해야 한다.사람이 작성하는 코드이므로 일부 필드를 누락할 가능성이 있다.필드의 수가 적다면 직접 변환 로직을 작성해도 문제가 없을 것이다. 그러나 필드가 수십 개 이상이거나 변환 로직이 복잡해질 경우, 실수로 인해 오류가 발생할 확률이 급격히 증가한다. 이때 MapStruct는 이러한 변환을 간결하게 처리..
3계층 아키텍처 vs 클린 아키텍처 비교표비교 항목3계층 아키텍처 (Three-Tier Architecture)클린 아키텍처 (Clean Architecture)구조Presentation (UI) 계층 Business Logic (Service) 계층 Data (Repository) 계층Entities (도메인 모델) Use Cases (비즈니스 로직) Interface Adapters (Controller, Presenter, Gateway) Frameworks & Drivers (DB, UI, External API)주요 개념계층별 역할을 나누어 관심사 분리의존성 방향을 내부(core)로 향하게 하여 높은 유지보수성과 테스트 용이성 제공의존성 흐름UI → Service → Repository (하위 ..
들어가며..이 글은 Spring Framework 없이 순수 Java로 프로젝트를 진행하며, 나의 사고 과정을 기록하고, 어떻게 이런 설계에 도달했는지를 설명하기 위해 작성된 글이다. 특히 User, Message, Channel과 관련된 Service Layer, Repository Layer 그리고 이들 간의 의존성 관리를 어떻게 설계했는지에 대한 고민과 해결 과정을 담고 있다.개요User, Message, Channel 에 대한 Service Layer, Repository Layer 와 이들 사이의 의존성 관리를 다루는 미션을 수행하는 과정에서의 일이다.1. 도메인별 팩토리 + 하드코딩된 의존성1.1 초기 구조처음 설계 단계에서는 SOLID 원칙을 준수하기 위해 Factory Pattern을 도입..
1. Class Loader SystemJVM 의 `Class Loader` 는 Java 프로그램 실행 시 필요한 클래스를 **동적** 으로 로드하는 역할을 한다. 즉, 프로그램 실행시 모든 클래스를 한번에 메모리에 올리는 것이 아닌, 특정 클래스가 필요할 때 해당 클래스 파일을 로드하고 초기화 시키기에 메모리 낭비를 막을 수 있다. `Class Loader` 는 기본적으로 loading - linking - initialization 의 과정을 거친다. 자세히 알아보자 1.1 Loading이 과정에서, 클래스 파일이 로드된다. 클래스 로더는 특정 클래스의 이름을 기반으로 클래스를 찾고, JVM 메모리에 읽어들인다. 이 과정속, 클래스 로더는 주요 3가지 로더를 거치는데, 이들은 계층형 구조를 띄며, 상..