JPA 알아야 할 내용
- jpa 내부 동작 방식(영속성 컨텍스트)
- 설계적인 측면(객체와 관계형 데이터를 어떻게 매핑해서 쓰는지)
- 연관관계 매핑
->어떤것이 어떤 것에 속해있는지
엔티티 매핑
객체와 테이블 매핑
@Entity
- @Entity가 붙은 클래스는 테이블과 매핑할 클래스
- 기본 생성자 필수(파라미터가 없는 public 또는 protected 생성자)
→ 리플랙션 같은 다양한 기술을 써서 객체를 프록싱하기도 하는데 이때 필요.
- 저장할 필드에 final 사용 X
→ 디비에 저장할 필드에는 final을 쓰면 안된다.
- 속성: name
- JPA에서 사용할 엔티티 이름을 지정한다.
- 기본값: 클래스 이름을 그대로 사용(예: Member)
@Table
- 엔티티와 매핑할 테이블을 지정
- 아래 코드와 같이 설정하면 insert 쿼리가 나갈때
insert into MBR ...
로 나간다.
@Table(name="MBR")
public class Member{}

데이터베이스 스키마 자동 생성
- JPA는 매핑정보만 보고 어떤 쿼리, 테이블을 생성해야 하는지 알 수 있다. 그래서 JPA는 어플리케이션 로딩 시점에 DB 테이블을 생성하는 기능을 지원해준다.
- DDL을 애플리케이션 실행 시점에 자동 생성
→ 애플리케이션 로딩 시점에 create문으로 DB를 생성하고 시작할 수 있다.
처음에 객체 매핑해놓으면 애플리케이션 뜰 때 필요한 테이블들을 만들어준다.
- 이렇게 생성된 DDL은 개발 장비에서만 사용
→ 운영에서는 사용하면 안된다.
데이터베이스 스키마 자동 생성 - 속성
hibernate.hbm2ddl.auto
- create : 기존테이블 삭제 후 다시 생성 (DROP + CREATE)
- create-drop : create와 같으나 종료시점에 테이블 DROP
- update : 변경분만 반영(운영DB에는 사용하면 안됨)
-> 지우는 작업은 안되고, 추가하는 작업만 가능하다.
- validate : 엔티티와 테이블이 정상 매핑되었는지만 확인
- none : 사용하지 않음
데이터베이스 스키마 자동 생성 - 주의
- 운영 장비에는 절대 create, create-drop, update 사용하면 안된다.
- 개발 초기 단계는 create 또는 update
- 테스트 서버는 update 또는 validate
- 스테이징과 운영 서버는 validate 또는 none
⇒ 로컬 피씨에서만 자유롭게 하고, 여러명이 쓰는 개발 서버나 스테이징이나 운영서버에는 가급적 쓰지 않는것을 권장한다.
DDL 생성 기능
- 제약조건 추가: 회원 이름은 필수, 10자 초과X
@Column(nullable = false, length = 10)
- 유니크 제약조건 추가
@Table(uniqueConstraints = {@UniqueConstraint( name = "NAME_AGE_UNIQUE", columnNames = {"NAME", "AGE"} )})
- DDL 생성 기능은 DDL을 자동 생성할 때만 사용되고 JPA의 실행 로직에는 영향을 주지 않는다.
필드와 컬럼 매핑
매핑 어노테이션 정리
hibernate.hbm2ddl.auto
@Column - 컬럼 매핑

@Temporal - 날짜 타입 매핑
날짜 타입(java.util.Date
, java.util.Calendar
)을 매핑할 때 사용
참고: LocalDate, LocalDateTime을 사용할 때는 생략 가능(최신 하이버네이트 지원)

@Enumerated - enum 타입 매핑
Enum타입을 쓸때는 기본이 ORDINAL이다. ORDINAL과 STRING을 쓸 수 있는데,
EnumType.ORDINAL
: enum 순서를 데이터베이스에 저장
EnumType.STRING
: enum 이름을 데이터베이스에 저장
→ ORDINAL을 사용하면 안되는 이유:
⇒ ENUM에 나중에 값이 하나 추가 되어서 USER, ADMIN
에서 GUEST, USER, ADMIN
으로 바뀌면 디비에 값을 저장하는데 혼란이 발생한다.
@Lob - BLOB, CLOB 매핑
@Lob private String description;
→ DB에 varchar보다 큰 컨텐츠를 넣고 싶으면 @Lob을 넣으면 된다.
매핑하는 필드 타입이 문자면 CLOB 매핑, 나머지는 BLOB 매핑
- CLOB:
String, char[], java.sql.CLOB
- BLOB:
byte[], java.sql. BLOB
@Transient - 특정 필드를 컬럼에 매핑하지 않음(매핑 무시)
@Transient private int temp;
-> DB랑 관련없이 메모리에서만 계산하고 싶은 변수가 있을경우, @Transient를 붙여주면 된다. 사용법은 위와 같다.
유니크 제약 조건
unique(DDL) 은 잘 안쓴다.
- 이름이 랜덤으로 생성돼서 쓰기 어려워 대신
@Table(uniqueConstraints)
으로 쓴다
기본 키 매핑
기본 키 매핑 어노테이션
기본 키 매핑 방법
- 직접 할당: @Id만 사용
- 자동 생성(@GeneratedValue)
→ 값을 자동으로 할당해주는 방법
- IDENTITY: 데이터베이스에 위임, MYSQL의 AUTO_INCREMENT
• 영속성 컨텍스트에서 관리되려면 무조건 pk값이 있어야 한다. 근데 IDENTITY 전략은 pk값이 데이터베이스에 들어간후에나 pk값을 알 수 있다. 그래서 JPA는 pk값이 없으니까 1차 캐시에 값을 넣을 수 없다. 그래서 IDENTITY 전략에서만 예외적으로 em.persist()를 호출한 시점에 디비에 insert쿼리를 날려버린다. (원래 커밋하는 시점에 쿼리가 날아간다.)
@Entity
public class Member {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
@Column(name = "name", nullable = false)
private String username;
}
- SEQUENCE: 데이터베이스 시퀀스 오브젝트 사용, ORACLE
• @SequenceGenerator 필요
- TABLE: 키 생성용 테이블 사용, 모든 DB에서 사용
• @TableGenerator 필요
- AUTO: 방언에 따라 자동 지정, 기본값
권장하는 식별자 전략
• 기본 키 제약 조건: null 아님, 유일, 변하면 안된다.
• 미래까지 이 조건을 만족하는 자연키는 찾기 어렵다. 대리키(대체키)를 사용하자.
• 예를 들어 주민등록번호도 기본 키로 적절하기 않다.
• 권장: Long형 + 대체키 + 키 생성전략 사용