회원 엔티티에서
@GeneratedValue로 기본키를 자동 생성하기로 함.
그런데 회원가입 시 아직 insert되기 이전에 createdBy 등록을 위해 userId가 필요한 상황이 발생함.👉 이 글에서 값 생성 시점을 기준으로
SEQUENCE와IDENTITY를 비교합니다.
em.persist() 호출 시 즉시 INSERT 쿼리가 실행됨@Entity
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long userId;
private String username;
}
User user = new User();
user.setUsername("홍길동");
em.persist(user); // 이 시점에 즉시 INSERT 쿼리 실행
System.out.println(user.getUserId()); // INSERT 전에는 null
persist() 시점에 즉시 INSERT 실행persist() 전에는 ID가 null@Entity
@SequenceGenerator(
name = "user_seq_generator",
sequenceName = "user_seq",
initialValue = 1,
allocationSize = 50
)
public class User {
@Id
@GeneratedValue(
strategy = GenerationType.SEQUENCE,
generator = "user_seq_generator"
)
private Long userId;
private String username;
}
User user = new User();
user.setUsername("홍길동");
em.persist(user); // Sequence 조회 → ID 할당 (INSERT는 아직 실행 안 됨)
System.out.println(user.getUserId()); // ID 조회 가능 (DB INSERT 전)
// 트랜잭션 커밋 시점에 실제 INSERT 실행
회원 생성 시 userId를 다른 로직에서 사용해야 하는데, 아직 DB에 INSERT되기 전인 경우:
@Service
@Transactional
public class UserService {
public Long createUser(UserCreateRequest request) {
User user = new User();
user.setUsername(request.getUsername());
em.persist(user);
// ❌ IDENTITY 사용 시: 이 시점에 이미 INSERT 실행됨
// ✅ SEQUENCE 사용 시: INSERT는 아직 실행 안 됨, ID만 할당됨
// userId를 createdBy에 추가
user.setCreatedBy(user.getUserId()); // ID 필요!
sendWelcomeEmail(user.getUserId()); // ID 필요!
return user.getUserId();
// 트랜잭션 커밋 시점에 실제 INSERT 실행 (SEQUENCE)
}
}
| 구분 | IDENTITY | SEQUENCE |
|---|---|---|
| ID 생성 시점 | DB INSERT 시 | persist() 호출 시 |
| INSERT 실행 시점 | persist() 호출 즉시 | 트랜잭션 커밋 시 |
| INSERT 전 ID 확보 | ❌ 불가능 | ✅ 가능 |
| 쓰기 지연 | ❌ 불가능 | ✅ 가능 |
| 배치 INSERT | ❌ 불가능 | ✅ 가능 |
| 지원 DB | MySQL, PostgreSQL 등 | Oracle, PostgreSQL, H2 등 |
| 성능 최적화 | 제한적 | allocationSize 활용 가능 |
@SequenceGenerator(
name = "user_seq_generator",
sequenceName = "user_seq",
allocationSize = 50 // 한 번에 50개씩 미리 할당
)
CREATE SEQUENCE user_seq INCREMENT BY 1 START WITH 1;
CREATE TABLE users (
user_id BIGINT PRIMARY KEY,
email VARCHAR(255)
);
spring.jpa.properties.hibernate.jdbc.batch_size=50
spring.jpa.properties.hibernate.order_inserts=true
spring.jpa.properties.hibernate.order_updates=true
INSERT 전에 ID가 필요한 경우에는 SEQUENCE 전략이 필수입니다. 회원 생성 시 userId를 다른 로직에서 사용해야 하는 상황이라면, SEQUENCE 전략을 통해 persist() 호출만으로 ID를 확보하고, 실제 INSERT는 트랜잭션 커밋 시점까지 지연시킬 수 있습니다. 이는 성능 최적화와 함께 비즈니스 로직의 유연성을 제공합니다.