인프런 커뮤니티 질문&답변

D Kim님의 프로필 이미지
D Kim

작성한 질문수

입문자를 위한 Spring Boot with Kotlin - 나만의 포트폴리오 사이트 만들기

[실습] 리포지토리 테스트 코드 작성

테스트코드 실패

해결된 질문

작성

·

71

0

안녕하세요, 테스트코드 결과가 계속 실패되는데... 이유를 찾지 못하여 질문 드립니다.

 

BeforeAll에서 projects를 디버그찍어 skills안의 skill확인 하면 제대로 들어간것이 보이는데,

image.png

 

테스트에 진입을 하면 skills가 0이 되는데...

image.png

다른 변수들은 다 들어가고 skills만 0이 되는 상황입니다...

 

어디서 부터 실수를 만든건지 파악이 안되어 도움을 요청드립니다.

 

아래 현재 문제가 있는 코드 남깁니다.

Git 저장소

답변 1

1

정보근님의 프로필 이미지
정보근
지식공유자

안녕하세요 정보근입니다:)

 

Project와 연결돤 ProjectSkill의 리스트가 조회가 안 되는 상황이었군요.

 

결론부터 말씀드리자면 이 경우는 Project 엔티티의 skills 필드의 OneToMany 어노테이션에

cascade 옵션이 빠져있었기 때문입니다.

 

cascade는 엔티티와 연결된 엔티티의 영속성 전이 타입을 정의합니다.

영속성이란 JPA에서 관리하는, 애플리케이션과 DB 사이의 레이어라고 보시면 됩니다.

이 영속성에 들어간 엔티티들이 최종적으로 DB 반영 대상이 되는데요.

 

@beforeAll에서 저희가 skill, project를 각각 만들어서 저장하고,

project를 만들 때에는 skills에 ProjectSkills까지 만들어서 리스트에 넣어줬습니다.

 

그럼 결과적으로 DB의 project, project_skill, skill 테이블에 데이터가 들어가는 게 저희가 원하는거죠?

하지만 이 때 DB를 살펴보면 project와 skill 테이블만 들어가고 project_skill은 비어있을거에요.

왜냐면 project와 skill은 명시적으로 save 메소드를 호출해줬지만

project_skill은 project 엔티티의 리스트에 넣어줬을 뿐이니깐요.

JPA에서 save를 호출해준 project와 skill만 영속성에 영속 상태로 만들기 때문에

project_skill은 트랜잭션이 종료되어도 별도의 인서트가 발생하지 않는 것입니다.

 

@OneToMany(mappedBy = "project", fetch = FetchType.LAZY, cascade = [CascadeType.PERSIST])
var skills: MutableList<ProjectSkill> = mutableListOf()

하지만 위 코드와 같이 CascadeType.PERSIST 옵션을 넣어주면,

Project 엔티티를 PERSIST(영속) 상태로 만들 때

연결된 ProjectSkill 엔티티도 같이 영속 상태로 만들어집니다.

상태가 cascade 되는거죠.

 

요약하면 ProjectSkill은 @BeforeAll에서 인스턴스가 만들어져 project에 들어갔고

그래서 디버깅에서 해당 인스턴스는 보여지지만,

Project의 영속 상태가 cascade 되지는 않았기 때문에 JPA 영속성 컨텍스트로 들어가진 않고,

따라서 DB에 인서트 되지도 않았던 것입니다.

그래서 이후에 조회해와도 project_skill 테이블에 데이터가 없기 때문에 비어있었던 것이고요.

 

감사합니다.

D Kim님의 프로필 이미지
D Kim

작성한 질문수

질문하기