스프링 부트에서 객체를 수정하기 위한 메서드를 작성할 때, 기존에는 아래와 같이 작성을 했다.
public SomeEntity updateEntity(Long id, SomeDto someDto) {
SomeEntity someEntity = someRepository.findById(id).orElseThrow(() -> new EntityNotFoundException("Entity not found"));
someEntity.setName(someDto.getName());
someEntity.setValue(someDto.getValue());
return someRepository.save(someEntity);
}
위와 같이 처음에는 find 메서드를 사용하여 객체를 탐색한 후, setter 메서드를 사용하여 이를 덮어쓰는 방식으로 수정 기능을 구현했다.
그런데 현재는 하단의 방법으로 대체를 하게 되었다.
@Entity
public class SomeEntity {
// ... 기존 필드와 메서드 ...
public void update(SomeDto someDto) {
this.name = someDTO.getName();
this.value = someDTO.getValue();
// ...
}
}
// 서비스 클래스 내의 메서드 ...
@Transactional
public void updateEntity(Long id, SomeDto someDto) {
SomeEntity someEntity = someRepository.findById(id).orElseThrow(() -> new EntityNotFoundException("Entity not found"));
someEntity.update(someDto);
// 트랙잭션이 끝날 때, 변경 사항이 자동으로 변경되기 때문에 save 함수를 사용할 필요가 없다.
}
}
위와 같이 save 메서드는 @Transactional 으로 대체하였고, setter 메서드는 직접 정의한 update 메서드로 대체하였다.
사실 JPA 에서 수정 기능을 구현할 때에는, save 메서드를 사용할 필요가 없다. 왜냐하면 트랙잭션 어노테이션에는 엔티티 객체의 상태 변화를 감지해주는 기능이 있기 때문이다. 정확히는 JPA의 영속성 컨텍스트와 데이터 베이스를 동기화 시켜주는 기능이라고 볼 수 있다. 또한 트랙잭션
즉, 저장도 알아서 해주고, 심지어는 오류가 나도 자동으로 롤백까지 해주는 방법으로 대체를 한 것이다. 고로 대체하지 않을 이유가 전혀 존재하지 않는다.
그리고, setter 메서드를 엔티티 클래스에서 직접 정의한 update 라는 메서드로 정의한 이유는 가독성이다. 개인적으로 setter 메서드로 되어 있으면 이 코드가 생성을 위한 코드인지, 수정을 위한 코드인지 구분하는 것이 번거로운 것 같아 교체하게 되었다.