테스트 환경에서 JPA update 안됨

· ☕ 2 min read · 👀... views

expect

  • JPA 를 사용하여 entity 를 변경했을 시 update 가 되야하지만, 테스트 코드에서 동작하지 않음.

situation

  1. Repository 를 상속한 곳에서 flush 메소드를 만든 후 호출

    -> 반응 없음 (sql log 에 update 가 출력 안됨)

  2. EntityManager 를 직접 호출하여 flush 수행

    -> No EntityManager with actual transaction available for current thread - cannot reliably process ‘flush’ call

  3. PersistenceContext 어노테이션 추가

1
2
3
@PersistenceContext(type = PersistenceContextType.EXTENDED)
// type PersistenceContextType.EXTENDED 을 추가
lateinit var entityManager: EntityManager

​ -> javax.persistence.TransactionRequiredException: no transaction is in progress

  1. Test Method 에 @Transactional 을 추가

    -> 정상적으로 업데이트 진행

  2. entityManager 의 flush 부분 삭제

    -> 정상적으로 업데이트 진행

  3. 1에서 진행했던 Repository 의 flush 메소드 호출 부분 삭제

    -> 정상적으로 업데이트 진행

  4. @Transactional 은 컨트롤러 상위든 메소드에든 상관 없이 동작

  5. Test 메소드가 끝나면 롤백되는 것을 확인

  6. 삽질을 하면서 AfterEach 사용했었는데.. (junit5 사용)

    -> 어찌보면 당연하겠지만, test 메소드의 라이프 사이클 내에 포함되는 것 같다.

    -> 즉, beforeEach - Test - afterEach 순으로 진행되며, afterEach 가 끝나야 롤백이 됨

  7. 사용하고자 하는 기능에 @Transactional 이 있기 때문에 Test 메소드에는 필요 없다고 생각했는데, 이게 잘못된 것 같음.

  8. flush 를 해주지 않아도 update 가 된다는 것은?? (추측)

    • 테스트 코드 부분
    1
    2
    3
    4
    5
    6
    7
    
    @Test
    @DisplayName("업데이트 성공")
    @Transactional
    internal fun success_update() {
        val updateReq = UpdateReq()
        updateService.update(updateReq)
    }
    
    • 서비스 코드 부분
    1
    2
    3
    4
    5
    6
    
    @Transactional
    fun updateBoard(req: UpdateReq) {
        .....
        val board = repository.findById(req.id)
        board.update(req)
    }
    

    -> 기존에는 테스트 코드 부분에 Transactional 이 없었기 때문에 서비스 코드 부분의 Transactional 이 계속 진행중? 이었으나, 테스트 코드 부분에 Transactional 을 추가함으로써 서로 격리가 되어, 서비스 부분의 Transactional 이 갖고 있는 context 는 더 진행할 것이 없기 때문에 update 가 되고, 서비스 객체 자체를 Test 의 Transactional 에 넘겨서 Test 에서 처리하게 하는 것이 아닌가 싶다. 아니면 롤백을 할 때는 서비스의 Transactional 을 수행해야 할 것 같으니, 순서? 같은 걸 스냅샷 같은 방법으로 남겨서 넘긴다던가??

conclusion

  1. 추측은 위험하지만, 당장의 지식으로 현 상황(삽질)을 정리하고 팠기에..
  2. @Transactional 에 대한 정리가 필요하다. (적당히 알았는데, 라이프 사이클이라던가 동작 방식을 확실히 알 필요가 생겼다.)
  3. 자세히 모르고 사용하는 JPA 가 문제인가 싶기도 하다. 영속성 컨텍스트 에 대한 이해도 필요하다. (문제해결을 위해 읽어봤으나, 당장 훑어봐서는 이해가 잘 안된다.)
    • 테스트 환경에서 JPA 주의점 을 봤지만 제대로 이해를 못했다. (내가 처한 것과 살짝 다른 것 같은 느낌도 들고 말이지..)
    • JPA 변경 감지 오늘의 글을 쓰게 해준 고마운 아티클 (처음에는 잘 모르는 상태에서 save 를 사용해서 update 를 했음…)
Share on

snack
WRITTEN BY
snack
Web Programmer


What's on this Page