기억용으로 작성하니 음슴체 쓰겠습돠
이번 토이프로젝트를 진행하면서 Querydsl 라이브러리를 사용하게 되었음..
위 ERD처럼 JPA ManytoMany 연관관계를 피하기 위해 중간테이블을 사용하여 연관관계를 맺어 구성하였음
List<MeetingEntity> meetingEntityList = queryFactory
.select(meetingEntity)
.from(meetingEntity)
.join(meetingEntity.meetingTechEntityList, meetingTechEntity).fetchJoin()
.join(meetingTechEntity.techEntity, techEntity).fetchJoin()
// .where(
// searchMeetingType(meetingSearchCondition.getMeetingType()),
// searchTech(meetingSearchCondition.getTechList())
// )
.fetch();
그래서 위처럼 fetch join을 활용하여 meetingEntity의 모든 정보를 가져오는 코드를 작성한 후
테스트 코드를 작성하여 돌려봤으나....
테스트코드 작성한대로라면 meetingTechEntityList의 size 는 2 가 나와야하는데 자꾸 0 이 나오는 상황이 펼쳐짐
그리하여 테스트코드를 잘못작성했나 몇번을 확인해봐도 이상한 점이 없었던 나는 2시간동안의 삽질끝에 이유를 찾았다.
바로 Rollback 테스트를 하기 위해 클래스 레벨에 작성한 @Transaction 어노테이션 때문이였던것
transaction 경계가 아닌 상황에서는 원하는 size 값인 2가 잘나옵니다.
하지만 왜 트랜잭션 상황에서는 원하는 querydsl 의 결과값이 안나오는지 확실하게 알고 싶어 계속계속 구글링을 해봤지만
결국 찾지 못하였고 ChatGpt에게 물어보니
지피티는 QueryDSL과 같은 데이터베이스 쿼리 작업은 별도의 트랜잭션 내에서 실행되지 않으면 정상적으로 동작하지 않을 수 있습니다. 라고 말해주네여 그리하여 @Trasaction 어노테이션을 둔 상태로 기존 save() 메소드에서 saveAndFlush()메서드로 변경해보았지만 size 는 0이 나오는 상황!! 그러다가 한줄기 빛이 옵니다 ㅠㅠ
https://cheese10yun.github.io/jpa-persistent-context/
계속해서 구글링 하다보니 JPA 영속성 컨텍스트를 사용할 시 주의점이라는 포스트를 보게되었고
요점은 findById() 와 같은 경우에는 영속성 컨텍스트를 먼저 찾고 영속성 컨텍스트에 해당 엔티티가 있으면 그 값을 바로 리턴
하지만 JPQL 인 Querydsl 의 경우에는 영속성 컨텍스트를 먼저 조회하지 않고 DB에서 먼저 값을 조회하게됨
위처럼 JPQL로 DB에 직접 질의를 한 이후에 가져온 meetingTechEntity의 정보는 이미 영속성 컨텍스트에 존재하므로
가져온 데이터를 버리게 된다. 그렇게 되면서 size가 0....
해결방법!!
- meetingEntity를 생성시 meetingEntity 객체에 meetingTechEntityList에 값을 추가하여 영속성 컨텍스트 1차캐시 통일
위의 방법을 통해 영속성 컨텍스트 1차 캐시의 값을 통일하여 원하는 테스트코드에서 원하는 값을 가져올 수 있음
'Spring' 카테고리의 다른 글
트랜잭션 전파 REQUIRES_NEW (0) | 2024.08.13 |
---|---|
Spring Security + jwt 사용기(우당탕탕 주의) - 3 (0) | 2023.05.02 |
Spring Security + jwt 사용기(우당탕탕 주의) - 2 (0) | 2023.04.04 |
Spring Security + jwt 사용기(우당탕탕 주의) - 1 (0) | 2023.03.31 |
Spring Filter에 대하여 (0) | 2023.03.15 |