섹션 1의 내용은 전반적인 프로젝트를 설정하는 내용이어서 따로 정리할 필요가 없을것 같았으나 ,
기본적인 내용들도 제대로 알지 못하는 나를 발견하고 정리를 한다.
[주요 복습 내용]
1. 스프링 프로젝트 설정 파일
: application.yml 파일로 설정
2. 엔티티의 생성자 제약사항
: protected의 기본생성자는 필수
3. 스프링 테스트시 습관적으로 붙여야 하는 어노테이션들
: @SpringBootTest , @Transactional , @Rollback(false) 의 기능
1. [스프링 프로젝트에서 사용하는 설정값들은 어떻게 명시해야 하지?]
[실제 사용한 application.yml 파일의 내용]
2. [엔티티의 생성자로는 반드시 protected의 기본 생성자가 포함되어있어야 함]
- 이는 따로 생성자를 정의하지 않는 경우라면 알아서 포함되므로 건드릴 필요 x
- 대신 우리의 username을 받는 생성자를 선언하는 경우처럼,
별도로 생성자를 정의한다면 - 기본생성자도 따로 정의해서 별도로 포함시켜야 함.
[public도 안되고 private도 안되고 , 반드시 protected여야 한다]
- private인 경우 JPA Proxy 기술이 이 엔티티에 적용이 안되기 때문
- public인 경우 아무 곳에서나 엔티티가 함부로 생성될 수 있기 때문
- 그래서 의무적으로 protected여야 한다. (JPA 표준 규약)
- 이를 별도로 정의해도 되지만,
@NoArgsConstructor(access = AccessLevel.PROTECTED)
어노테이션을 엔티티 클래스 Level에 추가하면
자동으로 어떤 파라미터도 받지 않는 기본생성자가 protected로 포함된다.
[실제 Member 엔티티의 모습]
3. [스프링 테스트시 의무적으로 붙인 어노테이션의 의미를, 이제는 기억하자!]
-
@SpringBootTest
- 스프링 빈을 의존관계 주입 받는 등의 스프링의 기능을 ,
테스트에서도 사용하고 싶다면,
(JUnit5 기반이어도) 반드시 붙여야 한다. (즉 필수)
-
@Transactional
- JPA의 모든 데이터 변경은 기본적으로 트랜잭션 안에서 이뤄져야 함.
- 그런데 Repository에는 이 어노테이션이 없어 트랜잭션이 걸리지 않으니,
테스트의 Class Level에 이 어노테이션을 붙여 - 모든 Method에 트랜젝션이 걸리도록 해야 함. (즉 필수)
- 기본적으로 readOnly옵션이 false 이므로 , 여기서 끝!
-
Rollback(false)
- 테스트가 아닌 일반 source 파일인 경우 필요 x
- 단 스프링 테스트인 경우 ,
@Transactional 에 나가는 쿼리는 모두 롤백된다!
- 사실 @Transactional 에 걸린 트랜젝션이 끝나도
트랜젝션이 flush 되지 않아 - 쿼리 자체가 안나간다!
- 그래서 DB에 어떤 데이터도 쌓이지 않는다!
- 따라서 실제 쿼리를 날려 , 어떤 쿼리가 나가는지도 보고 + DB에 쌓인 데이터도 보고싶다면 - 이렇게 롤백을 시키지 않아야 한다.
[나아가 트랜잭션이 commit된 후 flush되지 않으면 쿼리가 나가지 않게 되는데]
- 그래서 한 트랜젝션 안에서 엔티티를 생성-저장-조회 해도
- 그 엔티티는 결국 처음 생성된 엔티티가 , 그대로 영.컨 1차캐시에 남아있다가 , 꺼내지는 꼴 이므로
- 한 트랜젝션 안에서의 엔티티 객체는 - 같은 객체라는 사실이 보장된다!
- 그래서 결과적으로 우리의 테스트에서,
Member를 생성한채 - 영.컨에 넣고 - 그걸 다시 조회해도,
모두 같은 Member라는 테스트가 통과하게 된다!
(그래서 save() 한채 바로 반환해도 , 문제가 없었음!)
[실제 테스트 코드]