JPA Entity Mapping
객체의 Identity, Column, 관계와 생명주기를 Relational Table 규칙에 연결한다.
이 문서의 목차
Overview
Entity Mapping은 Java 객체의 Identity와 상태를 Table의 Primary Key, Column, Foreign Key에 대응시키는 규칙이다. Annotation을 붙이는 작업보다 객체 생명주기와 Database 제약을 일치시키는 설계가 핵심이다.
Entity 기본 조건
JPA가 관리할 Class는 @Entity로 표시하고 식별자를 가져야 한다. Proxy와 Reflection 기반 생성을 위해 접근 가능한 기본 생성자가 필요하며, Entity와 Persistent Field를 final로 제한하는 설계는 피한다.
Field Mapping
- Enum은 순서가 바뀌면 기존 값의 의미가 달라지는
ORDINAL보다STRING을 우선 검토한다. LocalDateTime은 현대 JPA 구현에서 Timestamp 계열에 Mapping할 수 있다.@Lob은 큰 Text/Binary 값을 표현하지만 실제 DB Type과 조회 비용을 확인한다.nullable, 길이, Unique 제약은 Application Validation과 별도로 Database에도 명시한다.
Primary Key 전략
IDENTITY는 Insert가 수행되어야 생성 값을 알 수 있으므로 persist 시점에 Insert가 필요하다. SEQUENCE는 Insert 전에 값을 확보할 수 있고 allocationSize로 Sequence 접근 횟수를 줄일 수 있다.
@SequenceGenerator(
name = "member_sequence",
sequenceName = "member_seq",
allocationSize = 50
)
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "member_sequence")
private Long id;flowchart LR; A[persist] --> B{PK 전략}; B -->|IDENTITY| C[INSERT 후 ID 반환]; B -->|SEQUENCE| D[ID 범위 확보]; D --> E[Persistence Context 등록]; C --> E관계 Mapping
Foreign Key를 실제로 변경하는 쪽을 연관관계의 주인으로 둔다. 양방향 관계의 반대편은 객체 탐색 편의를 위한 View이며, 편의 Method로 양쪽 객체 상태를 일관되게 유지한다. 모든 관계를 양방향으로 만들지 않는다.
실무에서 발생하는 문제
CascadeType.ALL을 Aggregate 경계 밖에 사용해 예상하지 못한 Entity가 저장·삭제된다.orphanRemoval을 단순한 DB Cascade Delete로 오해한다.equals/hashCode에 변경 가능한 Field나 Lazy 관계를 넣어 Collection 동작과 Query를 흔든다.- Database Migration과 Entity Mapping이 달라 운영에서만 오류가 발생한다.
Trade-off
풍부한 객체 Model과 변경 감지의 편의를 얻지만 SQL 실행 시점과 Join 비용이 코드 표면에서 멀어진다. Mapping은 Domain 편의뿐 아니라 Query Pattern과 Constraint를 함께 반영해야 한다.
Interview Questions
- IDENTITY와 SEQUENCE 전략은 Insert 시점에 어떤 차이가 있는가?
- 연관관계의 주인을 Foreign Key를 변경하는 쪽에 두는 이유는 무엇인가?
- Cascade와 orphanRemoval의 책임 범위는 어떻게 다른가?
- Enum ORDINAL이 장기 운영에서 위험한 이유는 무엇인가?
Related Topics
Persistence Context, Lazy Loading과 N+1, Fetch Join으로 Mapping 이후 실행 동작을 연결한다.
SOURCE REFERENCES
이 문서의 근거
본문은 Dev Atlas 안에서 완결되며, 검증이 필요할 때만 원문을 확인할 수 있습니다.