Study/spring

[Java] Spring Boot 3 JPA update 데이터 수정 사용법 및 예제

 

Spring Boot 3버전으로 spring-data-jpa update 기능을 사용하는 방법에 대해 설명드리겠습니다.

 

테이블, Repository 준비

update 기능을 실습할 엔티티와 리포지토리입니다.

// 엔티티 
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 UpdateTestEntity {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id", nullable = false)
    private Long id;

    @Column(nullable = false)
    private String name;
    
    public void changeName(String name) {
        this.name = name;
    }

}

//----------------------------

// 리포지토리
import org.springframework.data.jpa.repository.JpaRepository;

public interface UpdateTestRepository extends JpaRepository<UpdateTestEntity, Long> {
}

 

 

 

 

데이터 수정 예제

데이터를 등록할 때는 PK에 해당하는 식별자 값이 비어있어야 했는데, 데이터를 수정하고자 할 때는 수정하고자 하는 엔티티의 식별자가 있어야 합니다.

findById 메소드로 조회한 엔티티는 식별자가 포함되어있기 때문에 엔티티만 수정하면 됩니다.

 

 

save 메소드 사용

// 수정 전 엔티티 조회
UpdateTestEntity testEntity = repository.findById(1L).orElse(null);

// 데이터 수정
testEntity.changeName("changed name");

// 엔티티 수정(save 혹은 saveAndFlush)
repository.save(testEntity);
repository.saveAndFlush(testEntity);

saveAndFlush 메소드는 엔티티의 변경된 사항을 바로 반영하는 메소드입니다.

 

saveAndFlush 메소드는 테스트 코드 같은 곳에서 리포지토리의 save 메소드를 쓰면 실제로 수정은 되긴 하지만 update 쿼리를 확인할 수가 없어서 쿼리 확인을 위해 사용해보았습니다. 

 

식별자를 포함한 상태로 save 메소드를 실행하면 식별자를 가지고 조회 쿼리를 실행합니다.

[Hibernate] 
    select
        ute1_0.id,
        ute1_0.name 
    from
        update_test_entity ute1_0 
    where
        ute1_0.id=?

물음표 위치에 식별자를 넣고 실행이 되고, 식별자에 맞는 엔티티를 조회해 옵니다.

 

그리고 가져온 엔티티를 수정하고 save를 하게 되면 update 쿼리가 실행됩니다.

[Hibernate] 
    update
        update_test_entity 
    set
        name=? 
    where
        id=?

 

 

@Transaction과 함께 사용

@Transaction을 사용하면 save나 saveAndFlush 메소드를 직접 사용하지 않고도 update 쿼리를 실행할 수 있습니다.

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import lombok.RequiredArgsConstructor;

@Service
@RequiredArgsConstructor
public class UpdateService {

    private final UpdateTestRepository repository;

    @Transactional
    public void updateEntity() {
        UpdateTestEntity testEntity = repository.findById(1L).orElse(null);
        testEntity.changeName("change name");
    }
}

 

간단하게 설명하면, 메소드가 끝나는 시점에 변경사항이 감지되면 @Transactional에 의해 flush 메소드가 실행되어 JPA의 저장소에 쿼리가 저장되고, 트랜잭션이 종료되면 commit을 통해 수정 쿼리를 실행합니다.

 

save나 saveAndFlush를 통해 수정을 처리하기보다는 @Transactional에 의해 처리되도록 하는 것이 조금 더 좋은데, 그 이유는 save 메소드에 의해 불필요한 프로세스가 실행되기도 하지만, 수정 과정에서 오류가 발생하면 롤백처리도 되기 때문입니다.