아래처럼 @Transactional을 붙인 상태에서는 setFcmToken()에 따른 update문이 동작한다.
@SpringBootTest
@Commit
@Transactional
class CustomerRepositoryTest {
@Autowired
CustomerRepository customerRepository;
/**
* 없을 때 null을 반환하지는 않는다. 빈 리스트를 반환함.
*/
@Test
public void findBySnsTypeAndSnsIdentifyKeyTest() {
Customer customer = Customer.builder().build();
customerRepository.save(customer);
customer.setFcmToken("1");
List<Customer> li = customerRepository.findBySnsTypeAndSnsIdentifyKey(SNSType.NAVER, "1");//flush호출?
System.out.println(li);
if (li == null) {
System.out.println("null");
} else {
System.out.println("not null");
}
}
}
////아래는 결과!
Hibernate:
insert
into
customer
(created, modified, birth_year, email, fcm_token, gender, name, phone_num, sns_identify_key, sns_type, uuid)
values
(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
2022-08-12 17:54:10.894 TRACE 12676 --- [ main] o.h.type.descriptor.sql.BasicBinder : binding parameter [1] as [TIMESTAMP] - [2022-08-12T17:54:10.816035]
2022-08-12 17:54:10.894 TRACE 12676 --- [ main] o.h.type.descriptor.sql.BasicBinder : binding parameter [2] as [TIMESTAMP] - [2022-08-12T17:54:10.816035]
2022-08-12 17:54:10.894 TRACE 12676 --- [ main] o.h.type.descriptor.sql.BasicBinder : binding parameter [3] as [INTEGER] - [0]
2022-08-12 17:54:10.894 TRACE 12676 --- [ main] o.h.type.descriptor.sql.BasicBinder : binding parameter [4] as [VARCHAR] - [null]
2022-08-12 17:54:10.894 TRACE 12676 --- [ main] o.h.type.descriptor.sql.BasicBinder : binding parameter [5] as [VARCHAR] - [null]
2022-08-12 17:54:10.894 TRACE 12676 --- [ main] o.h.type.descriptor.sql.BasicBinder : binding parameter [6] as [VARCHAR] - [null]
2022-08-12 17:54:10.894 TRACE 12676 --- [ main] o.h.type.descriptor.sql.BasicBinder : binding parameter [7] as [VARCHAR] - [null]
2022-08-12 17:54:10.894 TRACE 12676 --- [ main] o.h.type.descriptor.sql.BasicBinder : binding parameter [8] as [VARCHAR] - [null]
2022-08-12 17:54:10.894 TRACE 12676 --- [ main] o.h.type.descriptor.sql.BasicBinder : binding parameter [9] as [VARCHAR] - [null]
2022-08-12 17:54:10.894 TRACE 12676 --- [ main] o.h.type.descriptor.sql.BasicBinder : binding parameter [10] as [VARCHAR] - [null]
2022-08-12 17:54:10.894 TRACE 12676 --- [ main] o.h.type.descriptor.sql.BasicBinder : binding parameter [11] as [BINARY] - [7addddde-bb14-477b-bb66-9ded01d5a806]
Hibernate:
update
customer
set
modified=?,
birth_year=?,
email=?,
fcm_token=?,
gender=?,
name=?,
phone_num=?,
sns_identify_key=?,
sns_type=?
where
uuid=?
2022-08-12 17:54:10.909 TRACE 12676 --- [ main] o.h.type.descriptor.sql.BasicBinder : binding parameter [1] as [TIMESTAMP] - [2022-08-12T17:54:10.878538200]
2022-08-12 17:54:10.909 TRACE 12676 --- [ main] o.h.type.descriptor.sql.BasicBinder : binding parameter [2] as [INTEGER] - [0]
2022-08-12 17:54:10.909 TRACE 12676 --- [ main] o.h.type.descriptor.sql.BasicBinder : binding parameter [3] as [VARCHAR] - [null]
2022-08-12 17:54:10.909 TRACE 12676 --- [ main] o.h.type.descriptor.sql.BasicBinder : binding parameter [4] as [VARCHAR] - [1]
2022-08-12 17:54:10.909 TRACE 12676 --- [ main] o.h.type.descriptor.sql.BasicBinder : binding parameter [5] as [VARCHAR] - [null]
2022-08-12 17:54:10.909 TRACE 12676 --- [ main] o.h.type.descriptor.sql.BasicBinder : binding parameter [6] as [VARCHAR] - [null]
2022-08-12 17:54:10.909 TRACE 12676 --- [ main] o.h.type.descriptor.sql.BasicBinder : binding parameter [7] as [VARCHAR] - [null]
2022-08-12 17:54:10.909 TRACE 12676 --- [ main] o.h.type.descriptor.sql.BasicBinder : binding parameter [8] as [VARCHAR] - [null]
2022-08-12 17:54:10.909 TRACE 12676 --- [ main] o.h.type.descriptor.sql.BasicBinder : binding parameter [9] as [VARCHAR] - [null]
2022-08-12 17:54:10.909 TRACE 12676 --- [ main] o.h.type.descriptor.sql.BasicBinder : binding parameter [10] as [BINARY] - [7addddde-bb14-477b-bb66-9ded01d5a806]
Hibernate:
select
customer0_.uuid as uuid1_1_,
customer0_.created as created2_1_,
customer0_.modified as modified3_1_,
customer0_.birth_year as birth_ye4_1_,
customer0_.email as email5_1_,
customer0_.fcm_token as fcm_toke6_1_,
customer0_.gender as gender7_1_,
customer0_.name as name8_1_,
customer0_.phone_num as phone_nu9_1_,
customer0_.sns_identify_key as sns_ide10_1_,
customer0_.sns_type as sns_typ11_1_
from
customer customer0_
where
customer0_.sns_type=?
and customer0_.sns_identify_key=?
2022-08-12 17:54:10.925 TRACE 12676 --- [ main] o.h.type.descriptor.sql.BasicBinder : binding parameter [1] as [VARCHAR] - [NAVER]
2022-08-12 17:54:10.925 TRACE 12676 --- [ main] o.h.type.descriptor.sql.BasicBinder : binding parameter [2] as [VARCHAR] - [1]
[]
not null
DB에도 잘 반영된 것을 알 수 있다.
@Commit을 떼고 실행해보았다. SQL은 똑같이 실행되지만 DB에서 확인할 수는 없었다. 테스트 환경에서는 @Transactional이 있으면 자동 롤백이다.
@Transactional, @Commit 둘 다 빼고 실행해보았다.
row는 하나가 생겼지만 fcm_token값은 들어오지 않았다.(sql을 확인해보면 update문은 실행되지 않았다.)
//실행 결과
Hibernate:
insert
into
customer
(created, modified, birth_year, email, fcm_token, gender, name, phone_num, sns_identify_key, sns_type, uuid)
values
(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
2022-08-12 18:06:37.174 TRACE 17200 --- [ main] o.h.type.descriptor.sql.BasicBinder : binding parameter [1] as [TIMESTAMP] - [2022-08-12T18:06:37.127444300]
2022-08-12 18:06:37.174 TRACE 17200 --- [ main] o.h.type.descriptor.sql.BasicBinder : binding parameter [2] as [TIMESTAMP] - [2022-08-12T18:06:37.127444300]
2022-08-12 18:06:37.174 TRACE 17200 --- [ main] o.h.type.descriptor.sql.BasicBinder : binding parameter [3] as [INTEGER] - [0]
2022-08-12 18:06:37.174 TRACE 17200 --- [ main] o.h.type.descriptor.sql.BasicBinder : binding parameter [4] as [VARCHAR] - [null]
2022-08-12 18:06:37.174 TRACE 17200 --- [ main] o.h.type.descriptor.sql.BasicBinder : binding parameter [5] as [VARCHAR] - [null]
2022-08-12 18:06:37.174 TRACE 17200 --- [ main] o.h.type.descriptor.sql.BasicBinder : binding parameter [6] as [VARCHAR] - [null]
2022-08-12 18:06:37.174 TRACE 17200 --- [ main] o.h.type.descriptor.sql.BasicBinder : binding parameter [7] as [VARCHAR] - [null]
2022-08-12 18:06:37.174 TRACE 17200 --- [ main] o.h.type.descriptor.sql.BasicBinder : binding parameter [8] as [VARCHAR] - [null]
2022-08-12 18:06:37.174 TRACE 17200 --- [ main] o.h.type.descriptor.sql.BasicBinder : binding parameter [9] as [VARCHAR] - [null]
2022-08-12 18:06:37.174 TRACE 17200 --- [ main] o.h.type.descriptor.sql.BasicBinder : binding parameter [10] as [VARCHAR] - [null]
2022-08-12 18:06:37.174 TRACE 17200 --- [ main] o.h.type.descriptor.sql.BasicBinder : binding parameter [11] as [BINARY] - [9144b42a-0b06-4ae7-9e34-cbe1c9e0a33f]
9144b42a-0b06-4ae7-9e34-cbe1c9e0a33f
Hibernate:
select
customer0_.uuid as uuid1_1_,
customer0_.created as created2_1_,
customer0_.modified as modified3_1_,
customer0_.birth_year as birth_ye4_1_,
customer0_.email as email5_1_,
customer0_.fcm_token as fcm_toke6_1_,
customer0_.gender as gender7_1_,
customer0_.name as name8_1_,
customer0_.phone_num as phone_nu9_1_,
customer0_.sns_identify_key as sns_ide10_1_,
customer0_.sns_type as sns_typ11_1_
from
customer customer0_
where
customer0_.sns_type=?
and customer0_.sns_identify_key=?
2022-08-12 18:06:37.252 TRACE 17200 --- [ main] o.h.type.descriptor.sql.BasicBinder : binding parameter [1] as [VARCHAR] - [NAVER]
2022-08-12 18:06:37.252 TRACE 17200 --- [ main] o.h.type.descriptor.sql.BasicBinder : binding parameter [2] as [VARCHAR] - [1]
[]
not null
<정리>
- @Transactional이 없다면 @Commit이 없어도 DB에 반영된다. @Transactional이 있으면 테스트 환경에서는 자동 롤백되기 때문에 @Commit을 붙여줘야한다.
- insert해야 얻을 수 있는 자동생성 uuid나 Auto Increment값은 @Commit하지 않아도 알 수 있다. 롤백은 반영했다가 지우는 것임.(따로 테스트 해보았다.) @Commit해야 알 수 있는 것 아니다.
- 테스트 코드에 @Transcational이 없으면 fcm_token의 수정이 반영되지 않았다. setFcmToken()에 따른 update문이 실행안됨.
3번을 살펴보자.
왜일까? @Transactional과 영속성컨텍스트의 생명주기와 관련이 있다.
- 영속성 컨텍스트는 @Transactional이 begin() 할 때 시작되고 commit() 하면 종료된다. (김영한 JPA 13장에서 확인할 수 있다.)
- 같은 @Transactional이라면 같은 영속성 컨텍스트에 접근한다.
두 가지 사실을 종합해보면 테스트 코드에서 @Transactional이 없다면 save한 이후에 영속성 컨텍스트는 종료된다. 그래서 setFcmToken()을 호출해도 영속성 컨텍스트가 종료되었기 때문에 update문이 나가지 않은 것이다.