[Spring] JPA - 프록시(Proxy)
·
Back end/Spring Project
1. em.find() vs em.getReference()엔티티를 조회할 때 JPA는 두 가지 방식을 제공합니다.em.find() ➡️ 즉시 로딩 데이터베이스를 통해 실제 엔티티 객체를 바로 조회합니다.즉시 쿼리가 실행됩니다.em.getReference() ➡️ 지연 로딩을 위한 가짜 객체(프록시) 반환 데이터베이스 조회를 미루는 프록시 객체를 반환합니다.필요할 때까지 쿼리가 실행되지 않고 대기합니다.2. 프록시란?프록시 객체는 JPA가 내부적으로 만들어 주는 가짜 객체입니다.하지만 실제 엔티티 클래스를 상속받아서 만들어지기 때문에 겉으로 보기에는 동일합니다.3. 프록시의 동작 원리프록시 객체는 내부적으로 실제 엔티티를 참조(target)로 보관합니다.프록시 객체를 호출하면 → 실제 엔티티의 메소드를 ..
[Spring] JPA - @MappedSuperclass
·
Back end/Spring Project
JPA를 사용하다 보면 여러 엔티티에서 공통으로 쓰이는 컬럼이 반복적으로 등장합니다.예를 들어, id, 생성일, 수정일, 작성자 같은 필드는 대부분의 엔티티에서 공통적으로 관리됩니다.이럴 때 JPA에서 제공하는 @MappedSuperclass를 사용하면 중복을 줄이고 깔끔하게 관리할 수 있습니다. 📖 @MappedSuperclass란?공통 매핑 정보를 모아두는 클래스엔티티가 아니며, 테이블과 직접 매핑되지 않음단순히 자식 엔티티에게 매핑 정보만 제공하는 역할따라서 em.find(BaseEntity) 같은 직접 조회는 불가능@MappedSuperclasspublic abstract class BaseEntity { @Id @GeneratedValue private Long id; p..
[Spring] JPA 양방향 연관관계와 연관관계의 주인
·
Back end/Spring Project
JPA에서 엔티티 간의 관계를 설정할 때 가장 중요한 개념 중 하나는양방향 연관관계와 연관관계의 주인(Owner) 입니다. 이는 데이터베이스 외래키(FK)를 누가 관리할지 결정하는 핵심 요소이므로 반드시 명확히 이해해야 합니다.🤔 연관관계의 주인이란?양방향 관계에서는 두 엔티티가 서로를 참조하지만,데이터베이스의 외래키는 단 한 곳에만 존재합니다. 따라서 JPA는 어떤 엔티티가 FK를 관리(등록·수정·삭제)할지 알아야 합니다.이 역할을 맡는 엔티티가 바로 연관관계의 주인(Owner) 입니다. 1:N 관계에서➡️ N(다) 쪽이 보통 외래키를 가지므로 주인이 됩니다.➡️ 1(일)은 mappedBy를 사용하여 자신이 주인이 아님을 명시해야 합니다.👉 즉, 1:N 관계에서는 항상 N 쪽이 주인이 됩니다.🤔 ..
[Spring] JPA 준영속 상태(Detached)
·
Back end/Spring Project
1. 준영속 상태란?준영속 상태(Detached)는 말 그대로 한 번 영속 상태였다가 영속성 컨텍스트와의 관계가 끊어진 상태를 말합니다.즉, 엔티티 객체는 여전히 메모리에 존재하지만 JPA가 해당 엔티티를 관리하지 않는 상태입니다.📌 영속 상태 → 준영속 상태 전환 시, 더 이상 1차 캐시나 변경 감지(Dirty Checking)가 동작하지 않습니다.2. 준영속 상태로 만드는 방법JPA에서 엔티티를 준영속 상태로 전환하는 방법은 크게 세 가지가 있습니다.em.detach(entity)→ 특정 엔티티만 준영속 상태로 전환합니다.em.clear()→ 영속성 컨텍스트를 완전히 초기화하여 모든 엔티티를 준영속 상태로 만듭니다.em.close()→ 영속성 컨텍스트를 종료합니다. (트랜잭션 종료 시 주로 발생)3..
[Spring] JPA flush
·
Back end/Spring Project
1. flush의 개념flush는 영속성 컨텍스트의 변경 내용을 데이터베이스에 반영하는 과정입니다.여기서 중요한 점은 영속성 컨텍스트를 비우지 않는다는 것입니다.즉, 1차 캐시(영속성 컨텍스트)는 그대로 유지되며, 단순히 SQL 저장소에 쌓여있던 쿼리들이 데이터베이스로 전송됩니다.2. flush의 특징1차 캐시(영속성 컨텍스트)는 유지됨→ clear()처럼 캐시를 비우지 않습니다.쓰기 지연 SQL 저장소의 쿼리를 DB에 반영→ em.persist()나 entity.setName() 등으로 변경된 내용을 DB에 즉시 보냅니다.트랜잭션을 끝내는 것이 아님→ flush() 호출 후에도 트랜잭션은 여전히 활성 상태입니다.동기화 목적→ JPQL 실행 전, 트랜잭션 커밋 직전에 DB와 영속성 컨텍스트를 맞추기 위해..
[Spring] JPA 기본 CRUD 동작 예제
·
Back end/Spring Project
JPA에서 제공하는 조회(Select), 등록(Insert), 수정(Update), 삭제(Delete) 기능은모두 영속성 컨텍스트와 밀접하게 연관되어 있습니다. 예제를 통해 각 기능의 실행 흐름과 콘솔 로그 결과를 확인해보겠습니다.1. 조회 – 1차 캐시 동작 확인EntityManager는 조회 시 먼저 1차 캐시를 확인하고,이미 같은 트랜잭션 내에서 조회한 엔티티라면 DB 쿼리를 실행하지 않습니다.try { // 1차 캐시 테스트 Member findMember1 = em.find(Member.class, 101L); // 첫 조회 → DB SQL 실행 Member findMember2 = em.find(Member.class, 101L); // 두 번째 조회 → 1차 캐시에서 반환 ..
[Spring] Maven profile 이용한 환경별 (local, dev, prod) 빌드 및 설정 분리
·
Back end/Spring Project
서비스를 운영하다 보면 로컬, 개발(dev), 운영(prod) 환경에 따라서로 다른 설정 파일을 사용해야 할 때가 많습니다. 이럴 때 Maven의 profile 기능을 활용하면,환경별로 유연하게 빌드 설정을 관리할 수 있습니다. 이 글에서는 Maven Profile을 활용해 환경별 설정을 관리하는 방법과 함께,리소스 경로를 유동적으로 지정하고 환경에 맞는 설정 파일을 로드하는 방법까지 살펴보겠습니다.💡 기본 구조1️⃣ 설정 파일이 기본 리소스 디렉터리에 존재할 경우- 파일명에 -dev, -prod 등의 프로파일명이 포함되어 있어야 자동 로드됩니다.src/main/resources/ ├─ application.properties ├─ globals-dev.properties ✅ └─ globals-p..
[Spring] BeanFactory와 ApplicationContext
·
Back end/Spring Project
스프링에서 빈(Bean)을 관리하는 핵심 컴포넌트는 스프링 컨테이너입니다. 그중에서도 가장 중요한 인터페이스가 바로 BeanFactory와 ApplicationContext인데요, 이 둘의 차이를 제대로 이해하면 스프링의 동작 원리를 더 쉽게 파악할 수 있습니다. 📌 스프링 컨테이너의 구조BeanFactory ↑ ApplicationContext ↑ AnnotationConfigApplicationContextBeanFactory: 가장 기본적인 스프링 컨테이너의 최상위 인터페이스 ApplicationContext: BeanFactory를 상속하여 확장한 인터페이스 AnnotationConfigApplicationContext: 자바 기반 설정(@Configuration)을 지원하는 실제 구..