⚡ 개요
save()와 saveAndFlush()의 차이점에 대해서 정리하기 전에 결론부터 얘기하면 두 개의 함수 모두 메서드가 끝나는 시점에 DB에 데이터가 저장이 된다. @Transactional 어노테이션에 따라서 동작하는 방식의 차이는 있을 수 있지만 결론은 동일하다.
아래의 사용 방법에 대해서 보기 전에 JPA 영속성에 대해서 잘 모른다면 한번 찾아보고 내용을 본다면 좀 더 도움이 된다.
추가적으로 JPA 영속화 과정에 대해서 정리를 하려고한다.
⚡ 사용 방법
📔 save()
entity 데이터 한건을 저장하는 데 사용을 하는 함수이다.
entity의 키의 존재 여부를 판단하고 신규 entity라고 판단을 하면 영속성 상태로 바꾸고 기존에 존재하는 entity이면 준영속 상태를 영속 상태로 바꿔준다.
@Transactional
public void test() {
user userDomain = userRepository.findById("testID");
userDomain.setName("test1");
// user1 에 값이 변경되면 자동으로 인지해 변경 사항을 반영 한다.
// userRepository.save(userDomain); // save 함수를 호출할 필요가 없다.
}
만약에 객체를 직접적으로 new로 생성을 해서 만들어서 영속성 데이터로 만들고 싶다면 save 함수를 호출해야 한다. 결국 repository를 통해서 조회를 했다면 save를 날리는 것 자체가 낭비가 된다고 보면 될 거 같다.
📔 saveAndFlush()
save() 호출하고 그 뒤에 DB에 flush() 한다.
위에서 처음에 설명했지만 실제 DB에는 반영되지 않는다. 그렇다면 이유가 궁금할 것이다.
JPA에서 flush()는 쿼리 저장소에 쿼리를 쌓지 않고 바로 쿼리를 날리는 것이다. 하지만 영속성 컨텍스트는 트랜젝션 범위 안에서만 동작을 하기 때문에 쿼리가 실행된다고 하더라도 실제로 DB에 반영되는 것이 아니다. 그래서 메서드가 끝나는 시점 (트랜젝션이 끝나는 시점)에서 DB에 반영이 된다.
트랜젝션이 끝나는 시점에 캐싱된 데이터들은 초기화가 된다.
@Transactional
public void test() {
user userDomain = userRepository.findById("testID");
userDomain.setName("test1");
// saveAndFlush 는 쿼리 저장소에 쿼리를 쌓지 않고 바로 쿼리를 날린다.
userRepository.saveAndFlush(userDomain);
}
⚡생각
JPA를 공부하면서 영속성에 대해서는 한 번쯤 들어봤을것이다. 영속성을 모른다면 위의 내용이 이해가 안갈수도 있기때문에 해당 내용을 공부해보는 게 좋을 거 같다.
'Spring' 카테고리의 다른 글
[JPA] Spring boot 3.x.x 에서 QueryDsl Date Type 사용 방법 (0) | 2024.01.09 |
---|---|
[Spring] Spring boot 3.x.x 버전 마이그레이션 내용 정리 (0) | 2023.12.31 |
[JPA] repository를 통해서 일부 컬럼만 조회하는 방법 정리 (0) | 2023.10.09 |
[QueryDsl] new CaseBuilder() 내용 정리 (0) | 2023.10.07 |
[Spring] Spring boot 3.0 + JPA 관련 gradle 설정 정리 (0) | 2023.09.25 |