엔티티 매핑은 어떻게 할까?
객체와 테이블 매핑
--
객체와 테이블을 매핑한다는 것은
특정 객체(클래스)를 DB의 테이블과 연결하여 해당 객체를 가지고 테이블을 관리할 수 있도록 구축하는 것이다.
JPA에서 객체와 테이블을 매핑하기 위해서 "@Entity"와 "@Table" 등의 어노테이션을 사용해야 한다.
@Entity
해당 클래스를 JPA가 관리하는 엔티티(Entity)로 사용하겠다고 선언하는 어노테이션이다.
(엔티티 = 테이블과 매핑되는 객체)
@Entity // 엔티티 선언
public class Member {
@Id // 기본 키 매핑
private Long id;
private String username;
...
}
@Entity를 선언하면
기본적으로 클래스명이 테이블명과 매핑된다.
즉, 클래스명이 Member면 테이블명도 동일한 Member와 매핑된다.
클래스(엔티티)에 정의한 필드들은 DB 테이블의 컬럼이 된다.
@Entity를 선언하면
직접 동일한 이름의 테이블을 생성하지 않아도
JPA가 자동으로 테이블을 생성하고 연결해준다.
1. 동일한 이름의 테이블이 존재한다면?
=> 새로 생성하지 않고 해당 테이블과 연결해 준다.
2. 기존 테이블이 존재하지만 엔티티 필드와 테이블의 컬럼 구성이 다르면?
=> 오류가 발생한다.
@Entity에 사용가능한 옵션(속성) 종류
- name : JPA에서 사용할 엔티티 이름을 지정한다.
@Entity(name = "User") // 엔티티 선언
public class Member {
@Id // 기본 키 매핑
private Long id;
private String username;
}
name 속성을 생략하면
기본값으로 클래스 이름을 그대로 테이블과 매핑하지만
name 속성을 사용하면
JPA는 해당 클래스(엔티티)를 name 속성값으로 정의한 엔티티명("User")으로 인식하여
클래스명은 "Member"지만 JPA는 해당 클래스(엔티티)를 "User"로 인식하여 사용한다.
@Entity의 name 속성은 해당 클래스의 엔티티명을 선언하는 속성으로 테이블명을 선언하는 속성이 아니다.
즉, 테이블명도 User가 아닌 그대로 클래스명과 동일한 Member가 된다.
동일한 클래스명이 있어서 충돌하는 상황이 아니라면 가급적 기본값으로 사용하는 것을 권장한다.
주의
name 속성을 사용하면 JPA가 Member 엔티티를 User로 인식하는 것이므로
코드를 작성할 때(직접 클래스를 참조할 때)에는 User가 아닌 그대로 Member를 사용해야 한다.
(JPA가 알아서 Member를 보고 User 테이블에 접근한다.)
// 엔티티 조회 (DB에서 값 가져오기)
Member member = em.find(Member.class, 1L); // 클래스명 사용
em.find()는 JPA가 엔티티를 직접 조회하는 메서드로
JPA가 해당 코드를 내부적으로 SQL로 변환해서 실행한다.
이때 JPA는 클래스명을 통해 엔티티를 인식하므로 엔티티명이 아닌 클래스명을 사용해야 한다.
과정
- JPA가 클래스명을 엔티티로 매핑 (= 해당 클래스의 JPA 엔티티 매핑 정보 조회)
- 해당 엔티티의 테이블명 조회 (= @Table의 name 속성을 확인)
- SQL로 변환 및 실행
// JPQL 사용
List<Member> members = em.createQuery("SELECT u FROM User u", Member.class)
.getResultList();
다만 JPQL은
JPA의 객체지향 쿼리 언어라서 SQL처럼 동작하지만
테이블이 아니라 엔티티를 대상으로 실행되므로
클래스명과, 테이블명이 아닌 엔티티명으로 작성해야 된다.
과정
- JPQL 파싱 (= 엔티티명을 확인 후 해당 매핑 정보를 찾아 해당 클래스와 연결)
- 해당 엔티티의 테이블명 조회 (= @Table의 name 속성을 확인)
- SQL로 변환 및 실행
즉, 간단하게 설명하면
@Entity의 name 속성은 해당 클래스에 대해 JPQL에서 사용할 엔티티명을 정의하는 것이다.
@Table
@Entity가 선언된 클래스에 추가로 선택하여 작성할 수 있는 어노테이션으로
해당 엔티티와 매핑될 테이블 정보를 설정할 수 있다.
@Table을 사용하지 않으면
기본적으로 클래스명이 테이블명이 되지만,
@Table을 사용하면 매핑될 테이블의 정보들을 직접 지정할 수 있다.
@Entity
@Table(name = "User") // DB에서 테이블명을 "User"로 설정
public class Member {
@Id
private Long id;
private String username;
}
@Table에 사용가능한 옵션(속성) 종류
- name : 매핑할 테이블명 설정
- schema : 특정 스키마에 테이블 생성 (데이터베이스 스키마 매핑)
- catalog : 특정 카탈로그에 테이블 생성 (데이터베이스 카탈로그 매핑)
- uniqueConstraints : DDL 생성 시 유니크 제약 조건 설정
정리
@Entity => 해당 클래스가 JPA의 엔티티임을 선언
@Table => 해당 엔티티가 매핑할 테이블 정보를 추가적으로 설정
@Entity의 name 속성 => 해당 클래스의 엔티티명 지정
@Talbe의 name 속성 => 해당 엔티티와 매핑될 테이블명 지정
--
데이터베이스 스키마 자동 생성
--
엔티티에서 매핑 정보들만 보면
어떤 쿼리를 만들어야 하는지, 어떤 테이블인지 전부 파악할 수 있다.
그래서 JPA는 애플리케이션 로딩 시점에 DB 테이블을 생성하는 기능을 지원한다.
(즉, 애플리케이션 실행 시점에 DDL을 자동으로 생성)
그래서 굳이 DB에서 따로 테이블을 만들지 않고 실행해도
작성한 엔티티에 알맞은 테이블이 자동으로 생성되어 서로 매핑되는 것이다.
이러한 기능은 운영환경에서 사용하면 안 되고
개발 단계인 경우에 도움이 된다.
애플리케이션을 재실행하면 기존 DB 데이터들이 전부 날아가고 새로 생성 후 매핑되기 때문이다.
이러한 설정을 application.yml 파일에서 설정할 수 있다.
spring.jpa.hibernate.ddl-auto = create
옵션 값 종류

사실 none이라는 옵션 값은 존재하지 않으며, 위 기존 옵션 값 외에 아무렇게 작성해도 적용된다.
다만 관례로 none이라고 작성한다.
주의
- 운영 환경에서는 절대 create, create-drop, update를 사용하면 안 된다. (기존 데이터가 삭제됨)
- 개발 초기에는 create 또는 update로 로컬 pc에서 사용
- 테스트 서버에는 update 또는 validate를 사용
- 스테이징 및 운영 서버에서는 validate 또는 none을 사용
DDL 생성 기능
엔티티 안에 각 필드에는 @Column 어노테이션을 선언할 수 있는데
@Column은 JPA에서 엔티티의 필드를 데이터베이스의 데이블 컬럼과 매핑할 때 사용된다.
@Column을 생략하면 기본적으로 필드명 그대로 테이블의 컴럼명으로 매핑되지만
@Column을 통해 매핑할 테이블의 컬럼명을 변경하거나 추가 설정을 할 수 있다.
@Table과 같이 다른 어노테이션들은 런타임마다 (INSERT, UPDATE 등) 영향을 주지만
@Column 옵션들은 DDL을 생성할 때만 영향을 주고 이후는 영향을 주지 않는다.
(즉, DDL 생성 이후 JPA의 실행 로직에 영향을 주지 않는다.)
--
엔티티에 사용되는 어노테이션 (+ 필드와 컬럼 매핑)
--
엔티티의 필드와 DB의 컬럼을 매핑하는 방법은 다양하다.
@Entity
public class Member {
@Id // PK로 매핑
private Long id;
@Column(name = "name") // DB의 컬럼명을 name으로 설정
private String username;
private Integer age; // Integer로 사용하면 DB에서 Integer와 가장 적절한 타입으로 설정됨
@Enumerated(EnumType.STRING) //해당 DB 컬럼을 enum타입으로 사용하여 매핑한다.
private RoleType roleType;
@Temporal(TemporalType.TIMESTAMP) //해당 DB 컬럼을 날짜 타입으로 사용한다.
private Date createdDate;
@Temporal(TemporalType.TIMESTAMP)
private Date lastModifiedDate;
@Lob // varchar보다 큰 값을 사용할 수 있게 한다.
private String description;
// Getter, Setter ...
}
위 코드처럼 엔티티를 작성하면 아래와 같이 SQL문이 실행된다.
create table Member (
id bigint not null,
age integer,
createdDate timestamp,
description clob,
lastModifiedDate timestamp,
roleType varchar(255),
name varchar(255),
primary key (id)
)
@Id
해당 필드를 DB 테이블의 PK(기본키)로 지정한다.
@GeneratedValue
해당 컬럼은 값이 자동으로 생성되도록 설정한다.
(주로 기본 키의 자동 증가를 설정하는 데 사용된다.)
"starategy" 속성을 통해 자동 생성 방식을 설정할 수 있다.
// AUTO : [기본값] 사용하는 DB의 방언에 따라 자동으로 설정된다.
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
사용하는 DB에 따라서 자동으로 값을 지정해 준다.
즉, DB에 따라서 IDENTITY, SEQUENCE, TABLE 방식 중에서 알맞은 옵션으로 사용된다.
[ MySQL에서는 IDENTITY를, Oracle에서는 SEQUENCE 방식을 사용한다.]
// IDENTITY : 사용하는 DB의 AUTO_INCREMENT를 사용한다. (MySQL에서는 값이 1식 자동 증가)
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
기본키의 생성을 그냥 DB가 알아서 하도록 위임한다.
즉, DB가 알아서 기본키를 자동으로 생성해 주므로 (ex. 1, 2, 3, ... 으로 채워진다.)
해당 필드에 값을 직접 넣어주면 안 된다. (넣으면 전부 null로 설정된다.)
// SEQUENCE : 사용하는 DB의 시퀀스 객체를 사용한다.
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE)
private Long id;
시퀀스 오브젝트를 만든 다음에 해당 시퀀스 오브젝트를 통해서 값을 가져온 것으로 세팅된다.
일반적으로 기본 시퀀스를 사용하지만
테이블마다 시퀀스를 따로 관리하고 싶다면
엔티티에 @SequenceGenerator 어노테이션을 사용하여 시퀀스마다 이름을 지어 각각 매핑해 줄 수 있다.
// TABLE : 키 생성 전용 테이블을 사용한다. (잘 사용하지 않음)
@Id
@GeneratedValue(strategy = GenerationType.TABLE)
private Long id;
키를 생성하는 전용 테이블을 하나 만든 다음 DB 시퀀스를 흉내 내어 사용한다.
(@TableGenerator가 필수로 필요)
모든 DB에 적용이 가능하지만 성능이 떨어진다.
@Column
DB 테이블의 컬럼과 매핑될 때 해당 컬럼에 대한 상세 설정을 할 때 사용된다.
@Column(name = "user_name", nullable = false, length = 100, unique = true)
private String username;

insertable, updatable 속성은
false로 설정하면 해당 컬럼을 추가하거나 값을 변경하려고 해도 절대 반영되지 않는다.
다만, JPA로 접근이 불가능하지 강제로 DB에서 SQL문으로 반영하는 것은 가능하다.
@Enumerated
해당 컬럼을 enum 타입으로 매핑할 때 사용된다.
즉, 자바의 enum을 DB에 저장할 때 사용한다.
(DB에는 enum 타입이 없지만 enum을 사용할 수 있게 만들어 준다.)
public enum Role {
USER, ADMIN
}
@Entity
public class Member {
@Enumerated(EnumType.STRING)
private Role role;
}

ORDINAL 속성은
enum의 정의된 순서(index)를 DB에 저장하는데
즉, enum에 값을 저장할 때 저장된 값의 순서를 Integer로 저장한다.
ORDINAL을 권장하지 않는 이유
처음에 enum에 USER를 저장하면 enum 안에는 USER 하나뿐이므로 0을 저장하게 된다.
이후 ADMIN을 저장하면 enum 안에는 USER, ADMIN이 저장되어 순서는 1이 저장된다.
그리고 GUEST를 저장하면 enum 안에는 GUEST, USER, ADMIN이 저장되어 순서는 0을 저장하게 된다.
즉, enum을 저장할 때 순서가 보장되지 않아서 저장되는 값이 중복될 수 있기 때문에 권장되지 않는다.
GUEST를 저장할 때 USER의 순서도 0 -> 1로 변경되는 것 아닌가?
이미 저장할 때 DB에 0으로 저장되었기 때문에 0으로 고정된다.
@Temporal
자바의 날짜 타입(java.util.Date, java.util.Calendar)을 DB 컬럼과 매핑할 때 사용된다.
@Temporal(TemporalType.TIMESTAMP)
private Date createdAt;

참고
자바 8부터는 LocalDate, LocalDateTime이 생겨서
하이버네이트에서도 해당 타입을 지원하기 때문에
JPA 2.1부터는 그냥 LocalDate, LocalDateTime 타입을 사용하면 알아서 매핑된다.
@Lob
DB의 대용량 데이터인 BLOB, CLOB 타입과 매핑할 때 사용된다.
@Lob
private String description;
@Lob에는 따로 속성이 없으며
매핑하는 필드의 타입에 따라 자동으로 BLOB 또는 CLOB으로 매핑된다.
- byte[], java.sql.BLOB : BLOB으로 매핑
- String, char[], java.sql.CLOB : CLOB으로 매핑
@Transient
특정 필드를 DB에 저장하지 않도록 설정한다.
즉, 필드와 컬럼을 매핑하지 않는다.
@Transient
private String tempData;
- 필드 매핑 X
- DB에 저장 X, 조회 X (즉, DB 테이블에 해당 컬럼을 생성하지 않음)
- JPA가 관리 X
- 주로 메모리상에서만 임시로 특정 값을 보관하고 싶을 때 사용된다.
--
참고 및 출처
'JPA' 카테고리의 다른 글
상속관계 매핑 (+@MappedSuperclass) (1) | 2025.04.01 |
---|---|
연관관계 매핑 (단방향, 양방향, 1:1, 1:N, N:1, N:N) (0) | 2025.03.31 |
영속성 관리 (내부 동작 방식) (0) | 2025.03.29 |
JPA 설정하기 (Spring boot 기준) (0) | 2025.03.25 |
JPA 개념 (0) | 2023.12.30 |
엔티티 매핑은 어떻게 할까?
객체와 테이블 매핑
--
객체와 테이블을 매핑한다는 것은
특정 객체(클래스)를 DB의 테이블과 연결하여 해당 객체를 가지고 테이블을 관리할 수 있도록 구축하는 것이다.
JPA에서 객체와 테이블을 매핑하기 위해서 "@Entity"와 "@Table" 등의 어노테이션을 사용해야 한다.
@Entity
해당 클래스를 JPA가 관리하는 엔티티(Entity)로 사용하겠다고 선언하는 어노테이션이다.
(엔티티 = 테이블과 매핑되는 객체)
@Entity // 엔티티 선언
public class Member {
@Id // 기본 키 매핑
private Long id;
private String username;
...
}
@Entity를 선언하면
기본적으로 클래스명이 테이블명과 매핑된다.
즉, 클래스명이 Member면 테이블명도 동일한 Member와 매핑된다.
클래스(엔티티)에 정의한 필드들은 DB 테이블의 컬럼이 된다.
@Entity를 선언하면
직접 동일한 이름의 테이블을 생성하지 않아도
JPA가 자동으로 테이블을 생성하고 연결해준다.
1. 동일한 이름의 테이블이 존재한다면?
=> 새로 생성하지 않고 해당 테이블과 연결해 준다.
2. 기존 테이블이 존재하지만 엔티티 필드와 테이블의 컬럼 구성이 다르면?
=> 오류가 발생한다.
@Entity에 사용가능한 옵션(속성) 종류
- name : JPA에서 사용할 엔티티 이름을 지정한다.
@Entity(name = "User") // 엔티티 선언
public class Member {
@Id // 기본 키 매핑
private Long id;
private String username;
}
name 속성을 생략하면
기본값으로 클래스 이름을 그대로 테이블과 매핑하지만
name 속성을 사용하면
JPA는 해당 클래스(엔티티)를 name 속성값으로 정의한 엔티티명("User")으로 인식하여
클래스명은 "Member"지만 JPA는 해당 클래스(엔티티)를 "User"로 인식하여 사용한다.
@Entity의 name 속성은 해당 클래스의 엔티티명을 선언하는 속성으로 테이블명을 선언하는 속성이 아니다.
즉, 테이블명도 User가 아닌 그대로 클래스명과 동일한 Member가 된다.
동일한 클래스명이 있어서 충돌하는 상황이 아니라면 가급적 기본값으로 사용하는 것을 권장한다.
주의
name 속성을 사용하면 JPA가 Member 엔티티를 User로 인식하는 것이므로
코드를 작성할 때(직접 클래스를 참조할 때)에는 User가 아닌 그대로 Member를 사용해야 한다.
(JPA가 알아서 Member를 보고 User 테이블에 접근한다.)
// 엔티티 조회 (DB에서 값 가져오기)
Member member = em.find(Member.class, 1L); // 클래스명 사용
em.find()는 JPA가 엔티티를 직접 조회하는 메서드로
JPA가 해당 코드를 내부적으로 SQL로 변환해서 실행한다.
이때 JPA는 클래스명을 통해 엔티티를 인식하므로 엔티티명이 아닌 클래스명을 사용해야 한다.
과정
- JPA가 클래스명을 엔티티로 매핑 (= 해당 클래스의 JPA 엔티티 매핑 정보 조회)
- 해당 엔티티의 테이블명 조회 (= @Table의 name 속성을 확인)
- SQL로 변환 및 실행
// JPQL 사용
List<Member> members = em.createQuery("SELECT u FROM User u", Member.class)
.getResultList();
다만 JPQL은
JPA의 객체지향 쿼리 언어라서 SQL처럼 동작하지만
테이블이 아니라 엔티티를 대상으로 실행되므로
클래스명과, 테이블명이 아닌 엔티티명으로 작성해야 된다.
과정
- JPQL 파싱 (= 엔티티명을 확인 후 해당 매핑 정보를 찾아 해당 클래스와 연결)
- 해당 엔티티의 테이블명 조회 (= @Table의 name 속성을 확인)
- SQL로 변환 및 실행
즉, 간단하게 설명하면
@Entity의 name 속성은 해당 클래스에 대해 JPQL에서 사용할 엔티티명을 정의하는 것이다.
@Table
@Entity가 선언된 클래스에 추가로 선택하여 작성할 수 있는 어노테이션으로
해당 엔티티와 매핑될 테이블 정보를 설정할 수 있다.
@Table을 사용하지 않으면
기본적으로 클래스명이 테이블명이 되지만,
@Table을 사용하면 매핑될 테이블의 정보들을 직접 지정할 수 있다.
@Entity
@Table(name = "User") // DB에서 테이블명을 "User"로 설정
public class Member {
@Id
private Long id;
private String username;
}
@Table에 사용가능한 옵션(속성) 종류
- name : 매핑할 테이블명 설정
- schema : 특정 스키마에 테이블 생성 (데이터베이스 스키마 매핑)
- catalog : 특정 카탈로그에 테이블 생성 (데이터베이스 카탈로그 매핑)
- uniqueConstraints : DDL 생성 시 유니크 제약 조건 설정
정리
@Entity => 해당 클래스가 JPA의 엔티티임을 선언
@Table => 해당 엔티티가 매핑할 테이블 정보를 추가적으로 설정
@Entity의 name 속성 => 해당 클래스의 엔티티명 지정
@Talbe의 name 속성 => 해당 엔티티와 매핑될 테이블명 지정
--
데이터베이스 스키마 자동 생성
--
엔티티에서 매핑 정보들만 보면
어떤 쿼리를 만들어야 하는지, 어떤 테이블인지 전부 파악할 수 있다.
그래서 JPA는 애플리케이션 로딩 시점에 DB 테이블을 생성하는 기능을 지원한다.
(즉, 애플리케이션 실행 시점에 DDL을 자동으로 생성)
그래서 굳이 DB에서 따로 테이블을 만들지 않고 실행해도
작성한 엔티티에 알맞은 테이블이 자동으로 생성되어 서로 매핑되는 것이다.
이러한 기능은 운영환경에서 사용하면 안 되고
개발 단계인 경우에 도움이 된다.
애플리케이션을 재실행하면 기존 DB 데이터들이 전부 날아가고 새로 생성 후 매핑되기 때문이다.
이러한 설정을 application.yml 파일에서 설정할 수 있다.
spring.jpa.hibernate.ddl-auto = create
옵션 값 종류

사실 none이라는 옵션 값은 존재하지 않으며, 위 기존 옵션 값 외에 아무렇게 작성해도 적용된다.
다만 관례로 none이라고 작성한다.
주의
- 운영 환경에서는 절대 create, create-drop, update를 사용하면 안 된다. (기존 데이터가 삭제됨)
- 개발 초기에는 create 또는 update로 로컬 pc에서 사용
- 테스트 서버에는 update 또는 validate를 사용
- 스테이징 및 운영 서버에서는 validate 또는 none을 사용
DDL 생성 기능
엔티티 안에 각 필드에는 @Column 어노테이션을 선언할 수 있는데
@Column은 JPA에서 엔티티의 필드를 데이터베이스의 데이블 컬럼과 매핑할 때 사용된다.
@Column을 생략하면 기본적으로 필드명 그대로 테이블의 컴럼명으로 매핑되지만
@Column을 통해 매핑할 테이블의 컬럼명을 변경하거나 추가 설정을 할 수 있다.
@Table과 같이 다른 어노테이션들은 런타임마다 (INSERT, UPDATE 등) 영향을 주지만
@Column 옵션들은 DDL을 생성할 때만 영향을 주고 이후는 영향을 주지 않는다.
(즉, DDL 생성 이후 JPA의 실행 로직에 영향을 주지 않는다.)
--
엔티티에 사용되는 어노테이션 (+ 필드와 컬럼 매핑)
--
엔티티의 필드와 DB의 컬럼을 매핑하는 방법은 다양하다.
@Entity
public class Member {
@Id // PK로 매핑
private Long id;
@Column(name = "name") // DB의 컬럼명을 name으로 설정
private String username;
private Integer age; // Integer로 사용하면 DB에서 Integer와 가장 적절한 타입으로 설정됨
@Enumerated(EnumType.STRING) //해당 DB 컬럼을 enum타입으로 사용하여 매핑한다.
private RoleType roleType;
@Temporal(TemporalType.TIMESTAMP) //해당 DB 컬럼을 날짜 타입으로 사용한다.
private Date createdDate;
@Temporal(TemporalType.TIMESTAMP)
private Date lastModifiedDate;
@Lob // varchar보다 큰 값을 사용할 수 있게 한다.
private String description;
// Getter, Setter ...
}
위 코드처럼 엔티티를 작성하면 아래와 같이 SQL문이 실행된다.
create table Member (
id bigint not null,
age integer,
createdDate timestamp,
description clob,
lastModifiedDate timestamp,
roleType varchar(255),
name varchar(255),
primary key (id)
)
@Id
해당 필드를 DB 테이블의 PK(기본키)로 지정한다.
@GeneratedValue
해당 컬럼은 값이 자동으로 생성되도록 설정한다.
(주로 기본 키의 자동 증가를 설정하는 데 사용된다.)
"starategy" 속성을 통해 자동 생성 방식을 설정할 수 있다.
// AUTO : [기본값] 사용하는 DB의 방언에 따라 자동으로 설정된다.
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
사용하는 DB에 따라서 자동으로 값을 지정해 준다.
즉, DB에 따라서 IDENTITY, SEQUENCE, TABLE 방식 중에서 알맞은 옵션으로 사용된다.
[ MySQL에서는 IDENTITY를, Oracle에서는 SEQUENCE 방식을 사용한다.]
// IDENTITY : 사용하는 DB의 AUTO_INCREMENT를 사용한다. (MySQL에서는 값이 1식 자동 증가)
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
기본키의 생성을 그냥 DB가 알아서 하도록 위임한다.
즉, DB가 알아서 기본키를 자동으로 생성해 주므로 (ex. 1, 2, 3, ... 으로 채워진다.)
해당 필드에 값을 직접 넣어주면 안 된다. (넣으면 전부 null로 설정된다.)
// SEQUENCE : 사용하는 DB의 시퀀스 객체를 사용한다.
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE)
private Long id;
시퀀스 오브젝트를 만든 다음에 해당 시퀀스 오브젝트를 통해서 값을 가져온 것으로 세팅된다.
일반적으로 기본 시퀀스를 사용하지만
테이블마다 시퀀스를 따로 관리하고 싶다면
엔티티에 @SequenceGenerator 어노테이션을 사용하여 시퀀스마다 이름을 지어 각각 매핑해 줄 수 있다.
// TABLE : 키 생성 전용 테이블을 사용한다. (잘 사용하지 않음)
@Id
@GeneratedValue(strategy = GenerationType.TABLE)
private Long id;
키를 생성하는 전용 테이블을 하나 만든 다음 DB 시퀀스를 흉내 내어 사용한다.
(@TableGenerator가 필수로 필요)
모든 DB에 적용이 가능하지만 성능이 떨어진다.
@Column
DB 테이블의 컬럼과 매핑될 때 해당 컬럼에 대한 상세 설정을 할 때 사용된다.
@Column(name = "user_name", nullable = false, length = 100, unique = true)
private String username;

insertable, updatable 속성은
false로 설정하면 해당 컬럼을 추가하거나 값을 변경하려고 해도 절대 반영되지 않는다.
다만, JPA로 접근이 불가능하지 강제로 DB에서 SQL문으로 반영하는 것은 가능하다.
@Enumerated
해당 컬럼을 enum 타입으로 매핑할 때 사용된다.
즉, 자바의 enum을 DB에 저장할 때 사용한다.
(DB에는 enum 타입이 없지만 enum을 사용할 수 있게 만들어 준다.)
public enum Role {
USER, ADMIN
}
@Entity
public class Member {
@Enumerated(EnumType.STRING)
private Role role;
}

ORDINAL 속성은
enum의 정의된 순서(index)를 DB에 저장하는데
즉, enum에 값을 저장할 때 저장된 값의 순서를 Integer로 저장한다.
ORDINAL을 권장하지 않는 이유
처음에 enum에 USER를 저장하면 enum 안에는 USER 하나뿐이므로 0을 저장하게 된다.
이후 ADMIN을 저장하면 enum 안에는 USER, ADMIN이 저장되어 순서는 1이 저장된다.
그리고 GUEST를 저장하면 enum 안에는 GUEST, USER, ADMIN이 저장되어 순서는 0을 저장하게 된다.
즉, enum을 저장할 때 순서가 보장되지 않아서 저장되는 값이 중복될 수 있기 때문에 권장되지 않는다.
GUEST를 저장할 때 USER의 순서도 0 -> 1로 변경되는 것 아닌가?
이미 저장할 때 DB에 0으로 저장되었기 때문에 0으로 고정된다.
@Temporal
자바의 날짜 타입(java.util.Date, java.util.Calendar)을 DB 컬럼과 매핑할 때 사용된다.
@Temporal(TemporalType.TIMESTAMP)
private Date createdAt;

참고
자바 8부터는 LocalDate, LocalDateTime이 생겨서
하이버네이트에서도 해당 타입을 지원하기 때문에
JPA 2.1부터는 그냥 LocalDate, LocalDateTime 타입을 사용하면 알아서 매핑된다.
@Lob
DB의 대용량 데이터인 BLOB, CLOB 타입과 매핑할 때 사용된다.
@Lob
private String description;
@Lob에는 따로 속성이 없으며
매핑하는 필드의 타입에 따라 자동으로 BLOB 또는 CLOB으로 매핑된다.
- byte[], java.sql.BLOB : BLOB으로 매핑
- String, char[], java.sql.CLOB : CLOB으로 매핑
@Transient
특정 필드를 DB에 저장하지 않도록 설정한다.
즉, 필드와 컬럼을 매핑하지 않는다.
@Transient
private String tempData;
- 필드 매핑 X
- DB에 저장 X, 조회 X (즉, DB 테이블에 해당 컬럼을 생성하지 않음)
- JPA가 관리 X
- 주로 메모리상에서만 임시로 특정 값을 보관하고 싶을 때 사용된다.
--
참고 및 출처
'JPA' 카테고리의 다른 글
상속관계 매핑 (+@MappedSuperclass) (1) | 2025.04.01 |
---|---|
연관관계 매핑 (단방향, 양방향, 1:1, 1:N, N:1, N:N) (0) | 2025.03.31 |
영속성 관리 (내부 동작 방식) (0) | 2025.03.29 |
JPA 설정하기 (Spring boot 기준) (0) | 2025.03.25 |
JPA 개념 (0) | 2023.12.30 |