본문 바로가기

카테고리 없음

엔티티 관련 어노케이션 정리하기

🏷️ @Entity

정의: 이 클래스가 JPA에서 관리되는 영속 엔티티 클래스임을 나타내는 어노테이션으로, DB 테이블과 매핑됨

 

더보기

✅ 장점

  • 해당 클래스가 JPA에 의해 자동으로 관리되고, 테이블과 매핑되어 SQL 없이 객체 기반 조작 가능
  • ORM 기반으로 도메인 중심의 개발 가능

❌ 단점

  • @Id 필드와 기본 생성자가 없으면 런타임 오류 발생
  • DTO(비즈니스 모델)와 Entity(영속 모델)를 혼용할 경우 책임 분리가 모호해짐
  • 필드가 많고 복잡해지면 유지 보수가 어려워질 수 있음

💡 사용 상황

  • DB 테이블과 직접적으로 매핑되는 핵심 도메인 모델을 정의할 때
  • 서비스의 주요 데이터 구조를 영속화할 필요가 있을 때

📌 규칙

항목 권장 사항
클래스명 보통 테이블의 이름과 비슷하게 (ex. Store)
위치 JPA 관리 대상은 도메인 패키지 하위에 위치
주의사항 반드시 @Id 필드 포함, 기본 생성자 존재해야 함

🏷️ @Table

정의: 엔티티가 매핑될 DB 테이블의 이름, 스키마, 인덱스 등을 지정할 수 있는 어노테이션

더보기

✅ 장점

  • 테이블 이름, 스키마 등을 명시적으로 설정할 수 있음
  • 실제 DB 테이블명과 클래스명이 다를 때 유용
  • 인덱스, 제약 조건 등을 설정할 수 있어 세밀한 매핑 제어 가능

❌ 단점

  • 이름을 잘못 지정하면 매핑 오류 발생 (런타임에서 문제 확인)
  • 유지보수 시 이름 변경 누락 등의 실수가 발생할 수 있음

💡 사용 상황

  • 클래스명과 테이블명이 일치하지 않는 경우
  •  
  • 다중 스키마, 복잡한 제약 조건이 필요한 경우

📌 규칙


항목  권장 사항
테이블명 단수형 사용 (store, user)
명명 규칙 스네이크 케이스 권장 (order_item)
일관성 유지 클래스와 매핑되는 테이블명은 프로젝트 전반에 걸쳐 동일 규칙 적용
설정 예시 @Table(name = "store")

🏷️ @Id

정의: 해당 필드가 엔티티의 기본 키(Primary Key)임을 지정하는 어노테이션

더보기

✅ 장점

  • 기본 키 지정으로 JPA가 엔티티를 식별하고 관리할 수 있음
  • 다른 어노테이션(@GeneratedValue, @ManyToOne 등)과 함께 조합 사용 가능

❌ 단점

  • 누락 시 런타임에서 예외 발생 (javax.persistence.PersistenceException)
  • 복합 키 사용 시 @Id 대신 @EmbeddedId, @IdClass와 같이 별도 학습 필요

💡 사용 상황

  • 각 엔티티의 고유 식별자 필드에 적용
  • 데이터베이스의 PRIMARY KEY에 대응되는 필드 설정 시

📌 규칙


항목  권장 사항
필드명 보통 id로 명명 (user_id 지양)
자료형 Long 또는 UUID 등 고유성 보장 타입
필수 설정 @Entity 클래스에는 반드시 1개 이상 필요

🏷️ @GeneratedValue

정의: @Id 필드의 기본 키 생성 전략을 설정하는 어노테이션으로, DB 또는 JPA가 식별자를 자동으로 생성할 수 있도록 한다.

더보기

전략별 정리


🔸 GenerationType.IDENTITY

  • 개념: DB의 AUTO_INCREMENT 또는 IDENTITY 컬럼 기능을 활용해 기본 키 자동 생성
  • 대표 DB: MySQL, MariaDB, SQL Server
  • 동작 방식:
    • INSERT 쿼리 실행 시점에 키 생성 → 영속성 컨텍스트의 쓰기 지연(Write-behind) 불가능
    • 즉, persist() 호출 즉시 DB에 insert 쿼리가 실행됨
  • 장점:
    • 설정이 간단하고 DB 기능 그대로 사용 가능
    • DB 차원에서 고유성 보장
  • 단점:
    • 쓰기 지연, 배치 처리 등의 성능 최적화가 어렵다
    • 키 생성을 DB에 위임하기 때문에 JPA의 일부 기능 제한
    • 테스트 시 MockDB 또는 H2와의 호환성 이슈가 생길 수 있음
  • 사용 상황:
    • 단순한 서비스에서 기본키를 자동 증가시키고자 할 때
    • MySQL 등에서 사용 시 기본적으로 적합
  •  

🔸 GenerationType.SEQUENCE

  • 개념: DB의 시퀀스 객체를 이용하여 식별자 생성
  • 대표 DB: Oracle, PostgreSQL
  • 동작 방식:
    • 시퀀스에서 미리 여러 개의 ID 값을 가져와 저장 → 쓰기 지연 및 배치 처리 최적화 가능
    • JPA의 @SequenceGenerator와 함께 사용
  • 장점:
    • 성능 우수 (시퀀스 미리 할당 가능)
    • 대량 INSERT에 유리 (allocationSize 조절로 batch insert 최적화 가능)
  • 단점:
    • 시퀀스 객체가 존재해야 하며, DB에 따라 지원 여부 다름
    • 설정이 약간 복잡
  • 사용 상황:
    • 성능 최적화가 중요한 서비스
    • Oracle, PostgreSQL 사용 시 가장 적합
  •  

🔸 GenerationType.TABLE

  • 개념: 키 생성을 위해 별도의 테이블을 사용해 ID를 관리
  • 대표 DB: 모든 DB에서 사용 가능 (호환성 최고)
  • 동작 방식:
    • id_generator 테이블에서 키 값을 읽고 증가시킨 후 사용
  • 장점:
    • 모든 DB에서 사용 가능
    • 시퀀스를 지원하지 않는 DB에서도 사용 가능
  • 단점:
    • 성능 저하가 크다 (매번 SELECT + UPDATE 발생)
    • 동시성 이슈, 락 경합 발생 가능
    • 실무에선 거의 사용하지 않음
  • 사용 상황:
    • 테스트용 DB, 또는 시퀀스가 없는 구형 DB에서만 사용
    • 전략 통일이 필요한 특수 상황
  •  

🔸 GenerationType.AUTO

  • 개념: JPA가 사용하는 DB 방언(dialect)을 참고하여 전략 자동 결정
  • 동작 방식:
    • DB에 따라 IDENTITY, SEQUENCE, TABLE 중 자동 선택
      • 예: MySQL → IDENTITY, Oracle → SEQUENCE
  • 장점:
    • 초기 개발 시 편리
    • DB 독립적인 코드 작성 가능
  • 단점:
    • 어떤 전략이 선택되는지 명확하지 않음
    • DB를 바꾸면 식별자 생성 방식이 달라짐 → 이슈 유발 가능
  • 사용 상황:
    • 실험적 프로젝트, DB가 아직 고정되지 않은 초기 단계

🏷️ @Column

정의: 엔티티의 필드를 DB 테이블의 컬럼과 매핑하는 어노테이션

더보기

✅ 장점

  • 컬럼명, 데이터 타입, 길이, NULL 여부 등 세부 설정 가능
  • 이름 충돌이 있을 때 명시적으로 컬럼명을 지정 가능
  • 유니크 제약이나 기본값 등도 설정 가능

❌ 단점

  • 모든 필드에 남용할 경우 불필요하게 복잡해질 수 있음
  • 잘못된 설정(길이 초과, nullable=false 등)은 런타임 또는 DB 레벨에서 오류 유발

💡 사용 상황

  • 컬럼명이 필드명과 다를 때
  • nullable, length, unique 등의 제약 조건을 설정하고 싶을 때
  • DB DDL 자동 생성 시 세밀하게 제어할 필요가 있을 때

📌 규칙

항목 권장 사항
컬럼명 명시적 지정 시 스네이크 케이스 사용 (user_name)
문자열 길이 length 명시 (VARCHAR 등 제한 시)
필수 여부 nullable = false 설정으로 제약 반영
유니크 여부 unique = true 설정 시 컬럼 레벨 유니크 적용

 

 

🎯 columnDefinition 상세 설명

정의: JPA가 생성하는 DDL에서 해당 컬럼의 타입 및 제약 조건을 직접 지정할 수 있는 속성


✅ 장점

  • DB에 의존적인 특수 타입(TEXT, JSON, ENUM, BOOLEAN, DATETIME 등) 지정 가능
  • 기본값, 인코딩 등 일반 속성으로 표현 불가한 제약 조건 명시 가능

❌ 단점

  • DB 종속적이므로 다른 DB로 마이그레이션 시 호환성 문제 발생 가능
  • 잘못된 SQL 문법 작성 시 런타임 오류 발생

💡 사용 상황

  • ENUM, JSON, TEXT, BOOLEAN 등 특수 타입 컬럼 매핑 시
  • DEFAULT, CHECK, COMMENT 등 DB-specific 제약 조건을 추가하고 싶을 때
  • 스키마 자동 생성 기능(hibernate.hbm2ddl.auto)을 쓸 때 세부 제어가 필요할 경우

🏷️ @ManyToOne

정의: JPA에서 다대일(N:1) 관계를 매핑할 때 사용하는 어노테이션
더보기

✅ 장점

  • 객체 관계를 명확히 표현하여 JOIN 없이 연관 엔티티 접근 가능
  • 외래 키 기반으로 자동 조인 수행 (지연 로딩 설정 가능)

❌ 단점

  • 양방향 관계일 경우 순환 참조 위험 (toString(), JSON 직렬화 등)
  • 잘못된 fetch 전략 사용 시 N+1 문제 발생 가능

💡 사용 상황

  • 여러 엔티티가 하나의 엔티티를 참조할 때 (예: 주문 → 회원, 상품 → 카테고리 등)
  • 외래 키 기반 연관 매핑이 필요한 경우

📌 규칙


 

항목 권장 사항
Fetch 전략 기본은 LAZY, 필요한 경우 EAG 권장 사항 ER 명시
연관 필드명 관계 의미가 명확한 이름 사용 (member, store 등)

 

 

🏷️ @JoinColumn

정의: 외래 키(FK)를 매핑할 컬럼을 지정하는 어노테이션

더보기

✅ 장점

  • 컬럼명, 제약 조건 등을 직접 지정 가능
  • 양방향 관계 시 외래 키의 주인을 명확히 설정 가능

❌ 단점

  • 외래 키 설정이 복잡해지면 양방향 관계 유지가 어려움
  • mappedBy 없는 잘못된 설정은 예상치 못한 테이블 구조 생성 가능

💡 사용 상황

  • 연관 관계의 주인 엔티티 쪽에서 FK 컬럼 명시할 때
  • 기본 전략의 컬럼명을 커스터마이징 하고 싶을 때

📌 규칙

항목 권장 사항
컬럼명 스네이크 케이스, _id 접미사 (member_id)
nullable 여부 NOT NULL 조건 필요 시 명시

🏷️ @OneToMany

정의: 일대다(1:N) 관계를 매핑할 때 사용하는 어노테이션

더보기

✅ 장점

  • 하나의 엔티티가 여러 자식 엔티티를 관리할 수 있음
  • 컬렉션을 통해 연관 객체에 쉽게 접근 가능

❌ 단점

  • 연관 관계의 주인이 아님 → 외래 키를 직접 관리하지 않음
    mappedBy 설정 필수
  • 잘못 사용하면 N+1 문제 발생
  • 양방향 설정 시 무한 순환 위험

💡 사용 상황

  • 게시글 → 댓글, 주문 → 주문상품 등
  • 자식 엔티티가 부모 엔티티를 외래 키로 참조하고 있는 경우

📌 규칙

항목 권장 사항
컬렉션 타입 List 사용 권장 (Set은 중복 제거용)
관계 주인 지정 항상 mappedBy 명시해야 성능 문제 방지
지연 로딩 fetch = FetchType.LAZY 기본 설정 유지
순환 참조 방지 @ToString.Exclude, @JsonIgnore 등 사용

🔄 Cascade 옵션 설명

정의: 부모 엔티티의 작업을 자식에게 함께 적용

옵션설명
PERSIST 부모 저장 시 자식도 저장됨 (save())
MERGE 부모 갱신 시 자식도 갱신됨 (save())
REMOVE 부모 삭제 시 자식도 삭제됨 (delete())
ALL 모든 cascade 적용 (PERSIST, MERGE, REMOVE 등)
DETACH, REFRESH JPA 컨텍스트에서만 사용되는 특수 옵션
 

💡 cascade = CascadeType.ALL 은 실무에서 매우 자주 사용되며, 특히 save()와 delete() 로직에서 유용합니다.


🗑️ 고아 객체 제거 (orphanRemoval)

정의: 부모 엔티티의 컬렉션에서 자식 엔티티가 제거되었을 때, 해당 자식을 자동으로 DB에서도 삭제해주는 기능

주의 사항

  • orphanRemoval = true 는 DELETE를 유발하므로 실수로 데이터 손실이 발생할 수 있음
  • 자식 객체가 다른 부모에 소속되지 않도록 설계되어 있어야 함

✅ 요약 규칙

항목권장 사항
컬렉션 초기화 new ArrayList<>() 명시적으로 해줘야 안전
mappedBy 설정 자식 객체에서 부모를 참조하는 필드 이름과 일치
지연 로딩 fetch = FetchType.LAZY 기본 유지
Cascade CascadeType.ALL 또는 필요한 옵션만 선택
orphanRemoval 삭제 추적이 필요할 경우에만 사용

🏷️ @MappedSuperclass

정의: JPA에서 공통 필드를 상속하기 위한 부모 클래스에 사용하는 어노테이션
이 클래스 자체는 테이블로 매핑되지 않음

더보기

✅ 장점

  • 엔티티 간 공통 필드(생성일, 수정일 등)를 재사용 가능
  • 코드 중복 제거, 일관된 엔티티 구조 유지

❌ 단점

  • DB에 테이블로 생성되지 않기 때문에 직접 쿼리 대상이 될 수 없음
  • 연관 관계(@OneToMany 등) 정의 불가능
    → 오직 필드 수준만 상속 가능
  • @EnableJpaAuditing,@EntityListeners(AuditingEntityListener.class) 사용해야 기능 구현

💡 사용 상황

  • 여러 엔티티에서 공통적으로 사용하는 필드(작성자, 시간 등)를 추출할 때
  • 엔티티 설계의 베이스 클래스로 활용할 때

📌 규칙

 

항목 권장 사항
클래스명 BaseEntity, BaseTimeEntity 등 명확하게
사용 어노테이션 @MappedSuperclass, @Getter, @SuperBuilder 등
필드 접근 방식 protected 또는 private + @Getter 사용

🏷️ @Embedded

정의: 엔티티 안에 값 객체(Value Object) 를 포함할 때 사용하는 어노테이션
해당 필드는 하나의 객체지만, 실제 DB에는 속성들이 컬럼으로 분해되어 저장됨

더보기

✅ 장점

  • 공통 속성을 객체로 추출해 코드 재사용 가능
  • 불변 값 객체로 만들기 적합 (setter 없이 생성자로만 설정)

❌ 단점

  • 테이블 구조상 분리되지 않음 → 동일 테이블에 컬럼이 분산됨
  • 컬럼명이 충돌할 수 있음 → @AttributeOverride로 대응 필요

💡 사용 상황

  • 주소, 기간, 전화번호 등 자주 쓰는 값 필드를 재사용할 때
  • 테이블을 분리하지 않고 한 엔티티에 포함시키고 싶을 때

📌 규칙


 

항목 권장 사항
필드 이름 의미 있는 객체 이름 사용 (e.g., address)
객체 내부 컬럼 충돌 방지 위해 @AttributeOverride 사용 가능

🏷️ @Embeddable

정의: @Embedded로 삽입될 값 객체 클래스에 사용하는 어노테이션
해당 클래스는 엔티티가 아니며, 직접 테이블로 매핑되지 않음

더보기

✅ 장점

  • 코드 재사용성 증가 (주소, 기간 등 여러 엔티티에서 공통 사용 가능)
  • 비즈니스 로직이 없는 값 객체 설계에 적합

❌ 단점

  • 식별자(ID) 없이 다른 엔티티에 포함되어야만 의미가 있음
  • 독립적인 조회, 저장이 불가능

💡 사용 상황

  • 여러 엔티티에서 공통으로 사용하는 필드 구조를 만들고 싶을 때

🏷️ @AttributeOverride

정의: @Embeddable 클래스가 여러 번 사용될 때, 각 필드의 컬럼명을 커스터마이징할 수 있도록 해주는 어노테이션

더보기

✅ 장점

  • 하나의 값 객체를 여러 곳에서 재사용하면서 컬럼명을 다르게 설정 가능
  • 컬럼 충돌 방지

❌ 단점

  • 설정이 누락되면 컬럼명이 중복되어 런타임 오류 발생

💡 사용 상황

  • 동일한 @Embeddable 클래스를 두 번 이상 포함해야 할 때
  • 기존 DB 스키마에 맞춰 컬럼명을 다르게 지정하고 싶을 때

🏷️ @SQLDelete

정의: 엔티티가 삭제될 때 물리적 삭제 대신 사용자 정의 SQL을 실행하게 해주는 Hibernate 어노테이션

더보기

✅ 장점

  • 소프트 삭제(soft delete) 구현 가능
    (실제 삭제 대신 상태 값만 변경)
  • 로그, 이력 관리 등 데이터 유지에 유리

❌ 단점

  • 일반 JPA 기능이 아닌 Hibernate 전용 기능 (이식성 낮음)
  • 삭제 쿼리가 항상 실행되므로 성능과 트랜잭션 주의 필요

💡 사용 상황

  • 데이터를 실제로 삭제하지 않고 status, deleted_at 등의 컬럼으로 삭제 처리할 때
  • 데이터 복구, 감사 로직 등 유지 관리가 중요한 경우

📌 규칙


항목 권장 사항
쿼리 구조 UPDATE로 상태 컬럼을 변경하도록 작성
WHERE 조건 주의 id = ? 로 매핑되므로 기본키 필수

https://dzone.com/articles/all-jpa-annotations-mapping-annotations

 

All JPA Annotations: Mapping Annotations

Let's take a look at this quick overview of all 89 JPA mapping annotations in Java with use cases and more!

dzone.com