본문 바로가기
IT

[Spring Boot 3] JPA를 이용한 데이터 등록(insert) 완벽 가이드

by 굿센스굿 2025. 5. 9.
반응형

 

Spring Boot 3는 자바 백엔드 개발에서 가장 널리 사용되는 프레임워크 중 하나입니다. 그 중에서도 데이터베이스와의 통신을 단순화해주는 spring-data-jpa는 생산성을 크게 향상시켜주는 도구입니다. 이번 포스팅에서는 Spring Boot 3 환경에서 JPA를 활용하여 데이터베이스 테이블에 데이터를 등록(insert)하는 방법을 실습 예제와 함께 매우 상세하게 정리해보겠습니다.


✅ JPA를 사용한 데이터 등록 흐름 개요

데이터를 등록하는 기본적인 흐름은 다음과 같습니다.

  1. 엔티티(Entity) 클래스 생성
  2. Repository 인터페이스 생성
  3. 서비스 혹은 컨트롤러에서 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를 활용해 안정적이고 깔끔한 데이터 등록 로직을 구현해보시기 바랍니다!

 

반응형