Spring Boot 3는 자바 백엔드 개발에서 가장 널리 사용되는 프레임워크 중 하나입니다. 그 중에서도 데이터베이스와의 통신을 단순화해주는 spring-data-jpa는 생산성을 크게 향상시켜주는 도구입니다. 이번 포스팅에서는 Spring Boot 3 환경에서 JPA를 활용하여 데이터베이스 테이블에 데이터를 등록(insert)하는 방법을 실습 예제와 함께 매우 상세하게 정리해보겠습니다.
✅ JPA를 사용한 데이터 등록 흐름 개요
데이터를 등록하는 기본적인 흐름은 다음과 같습니다.
- 엔티티(Entity) 클래스 생성
- Repository 인터페이스 생성
- 서비스 혹은 컨트롤러에서 save() 메서드를 호출하여 데이터 저장
이제 각 단계별로 코드와 함께 자세히 설명드리겠습니다.
🧱 Step 1. Entity 클래스 생성
JPA에서 테이블과 1:1로 매핑되는 클래스를 엔티티(Entity) 라고 합니다. 먼저 데이터를 저장할 테이블에 대응하는 엔티티 클래스를 생성합니다.
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
@Entity
@Getter
@NoArgsConstructor
@AllArgsConstructor
public class InsertTestEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id", nullable = false)
private Long id;
@Column(nullable = false)
private String name;
private Integer birthYear;
}
💡 설명
- @Entity: 이 클래스가 데이터베이스 테이블과 매핑된다는 의미입니다.
- @Id: 이 필드가 테이블의 기본 키(PK)라는 의미입니다.
- @GeneratedValue: PK 값이 자동 생성되도록 지정합니다. IDENTITY 전략은 DB의 auto_increment를 의미합니다.
- @Column: 컬럼 정보를 추가로 설정할 수 있습니다. 예: nullable, name, length 등.
이 엔티티는 아래와 같은 테이블로 매핑됩니다.
create table insert_test_entity (
id bigint not null auto_increment,
birth_year integer,
name varchar(255) not null,
primary key (id)
) engine=InnoDB
📚 Step 2. Repository 생성
JPA는 엔티티와 데이터베이스 간의 CRUD 작업을 수행하는 리포지토리 인터페이스를 제공합니다.
import org.springframework.data.jpa.repository.JpaRepository;
public interface InsertTestRepository extends JpaRepository<InsertTestEntity, Long> {
}
📌 핵심 포인트
- JpaRepository<엔티티, PK 타입>을 상속받으면 기본적인 CRUD 메서드를 모두 사용할 수 있습니다.
- 별도의 구현 없이도 save, findById, deleteById 등 다양한 메서드를 활용할 수 있습니다.
📝 Step 3. 데이터 등록 예제
이제 실제로 데이터를 등록해보겠습니다. 주의할 점은 PK 필드의 값은 반드시 null이어야 insert가 정상 작동합니다.
@Autowired
private InsertTestRepository repository;
...
InsertTestEntity entity = new InsertTestEntity(null, "홍길동", 1990);
InsertTestEntity savedEntity = repository.save(entity);
🔍 save() 작동 방식
- save() 메서드는 엔티티의 ID가 null인 경우 INSERT 쿼리를 실행합니다.
- ID가 존재하면 UPDATE 쿼리를 실행합니다.
💬 실행 로그 예시
[Hibernate]
insert
into
insert_test_entity
(birth_year, name)
values
(?, ?)
⚠️ 주의할 점 및 자주 발생하는 에러
1. Field '<필드명>' doesn't have a default value
Field 'name' doesn't have a default value
- 컬럼이 nullable = false로 지정되어 있는데 해당 필드 값이 비어 있을 때 발생합니다.
- 해결: 해당 필드에 값을 지정하거나, 엔티티에서 nullable = true로 설정합니다.
2. Identifier of entity must be manually assigned before calling 'persist()'
org.springframework.orm.jpa.JpaSystemException: Identifier of entity 'InsertTestEntity' must be manually assigned...
- PK에 값을 지정하지 않았고, @GeneratedValue도 빠져있을 때 발생합니다.
- 해결: @GeneratedValue(strategy = GenerationType.IDENTITY)를 통해 자동 생성되도록 설정해야 합니다.
3. save()를 반복적으로 사용했는데도 INSERT가 되지 않는 경우
- @Transactional이 누락되었거나, save 이후 flush가 안 되어서 발생하는 경우가 있습니다.
- 해결: 서비스 계층에서 @Transactional을 선언하거나 repository.saveAndFlush(entity) 사용.
✅ 실습 예제 3가지
예제 1: 기본적인 사용자 등록
InsertTestEntity user = new InsertTestEntity(null, "김영희", 1985);
repository.save(user);
예제 2: null 컬럼 허용 확인
InsertTestEntity user = new InsertTestEntity(null, "이철수", null);
repository.save(user); // birthYear는 null이어도 저장 가능
예제 3: 잘못된 등록 - name 필드 누락
InsertTestEntity user = new InsertTestEntity(null, null, 2000);
repository.save(user); // 오류 발생: name은 not null
🔄 save()와 persist() 차이
- save()는 JPA의 merge()를 래핑한 메서드로, ID가 있으면 update, 없으면 insert입니다.
- persist()는 무조건 insert이며, ID가 있어서는 안 됩니다.
Spring Data JPA를 사용할 경우 save() 하나로 대부분의 저장 기능을 처리할 수 있기 때문에 실제로 persist()를 직접 사용할 일은 많지 않습니다.
🧪 테스트 코드로 검증하기
JUnit을 활용하여 저장 기능을 테스트할 수도 있습니다.
@SpringBootTest
class InsertTestRepositoryTest {
@Autowired
private InsertTestRepository repository;
@Test
void insertTest() {
InsertTestEntity user = new InsertTestEntity(null, "테스트", 2001);
InsertTestEntity saved = repository.save(user);
assertNotNull(saved.getId());
assertEquals("테스트", saved.getName());
}
}
💡 마무리 및 정리
Spring Boot 3 환경에서 JPA를 사용한 데이터 등록은 굉장히 단순하지만, PK의 자동 생성 전략, not null 필드, save() 메서드의 작동 방식에 대한 이해가 부족하면 쉽게 오류가 발생할 수 있습니다. 아래 내용을 꼭 기억하세요.
항목 설명
@Entity | 엔티티 선언 |
@Id + @GeneratedValue | 기본 키 자동 생성 |
save() | ID 없으면 insert, 있으면 update |
@Column(nullable = false) | 필수 값 지정 |
에러 해결 | not null 필드, PK 자동 생성 문제 |
Spring Boot + JPA 조합은 대규모 웹 애플리케이션에서도 충분히 견고한 데이터 처리를 가능하게 합니다. 단순한 예제로 시작하더라도, 그 안에 숨어 있는 규칙과 흐름을 잘 파악하는 것이 중요합니다.
이제 여러분의 프로젝트에서도 JPA를 활용해 안정적이고 깔끔한 데이터 등록 로직을 구현해보시기 바랍니다!
'IT' 카테고리의 다른 글
[Spring Boot 3] @Valid 예외 처리 완전 정복: MethodArgumentNotValidException vs BindException (0) | 2025.05.09 |
---|---|
[Spring Boot 3] @DateTimeFormat을 활용한 날짜 유효성 검사 완전 정복 (0) | 2025.05.09 |
Spring Boot 3 JPA에서 데이터 수정(Update)하는 가장 깔끔한 방법과 예제 (0) | 2025.05.09 |
비주얼 스튜디오 코드(VSCode) 확장 프로그램 추천 총정리 🔧 (2) | 2025.05.08 |
웹 서버(Web Server)와 웹 애플리케이션 서버(WAS)의 차이점, 쉽게 정리해드립니다 (0) | 2025.05.08 |