오늘도 Spring 강의 내용을 복습하면서 과제를 진행해보는 시간을 주로 가졌다. 틈틈이 CS 공부도 병행하고 있다. 코드적인 부분만큼이나 이론적인 부분이 중요하다는 걸 점점 깨닫게 되는 것 같다.
여기에는 지난번에 해결하지 못했던 Response Body에 최종 업데이트 시간이 제대로 출력되지 않은 문제를 해결한 내용을 정리해보았다. 튜터님에게 질문해보고 힌트를 얻고 해결해보았던 내용을 적어본다.
1. Spring 개인 과제
오늘은 지난번에 해결하지 못했던 문제를 해결했던 내용을 적어본다.
지난번 있었던 문제를 다시 적어본다.
PUT 메소드를 이용해서 수정을 했을 경우 위 사진과 같이 최종 수정 시간이 Response Body에 제대로 표시가 되지 않고, 이전 DB에 저장되어 있는 값이 불러와지는 문제가 있었다. DB에 실제로 최종 수정 시간은 잘 저장되었지만 Response Body의 값이 변경되지 않는 문제가 있었다.
@Transactional
override fun updateTodo(todoId: Long, request: UpdateTodoRequest): TodoResponse {
val todo = todoRepository.findByIdOrNull(todoId) ?: throw TodoNotFoundException(todoId)
todo.name = request.name
todo.title = request.title
todo.description = request.description
return todoRepository.save(todo).toResponse()
}
업데이트를 하는 함수에 문제가 있을 것이라는 것은 쉽게 예상이 갔고, 처음에는 쉽게 문제를 해결할 수 있을 줄 알았는데, JPA의 작동원리를 제대로 몰라서 문제를 제대로 파악조차 하지 못하고 있었던 것이었다.
위 그래프는 EntityManager가 지원하는 여러가지 함수들과, 엔티티의 상태들이 어떻게 변경되는지를 나타낸다.
이제 내가 쓴 코드에서 사용했던 save함수가 어떻게 동작하는지를 알아야한다.
save 함수는 먼저 엔티티가 새로운 엔티티인지 아닌지를 판단해서 새로운 엔티티이면 persist()를 수행하고 그렇지 않으면 merge()를 수행하게 된다. 위에서 문제가 된 것은 업데이트를 하는 과정에서 발생한 것이고 DB에서 엔티티를 가져온 뒤에 그 안에 있는 값을 수정한 것이기 때문에 merge()가 되게 된다.
save 함수는 딱 merge() 까지만 수행하고 updateTodo()의 모든 동작이 끝난 뒤 flush()를 하게 된다. flush()를 해서 DB의 값이 업데이트 되어야지만 최종 수정 시간이 변하기 때문에, save까지만 한 뒤에 엔티티를 Response Body로 바꿔서 반환시키면 그 안에 있는 최종 수정 시간이 업데이트가 되지 않았던 것이다.
이제 원인을 알았으니 코드만 수정하면 된다. 원인을 알고나니 코드 수정은 너무나도 간단하다.
@Transactional
override fun updateTodo(todoId: Long, request: UpdateTodoRequest): TodoResponse {
val todo = todoRepository.findByIdOrNull(todoId) ?: throw ModelNotFoundException("Todo", todoId)
todo.title = request.title
todo.name = request.name
todo.description = request.description
// flush를 해준다
todoRepository.flush()
// 그 다음 Entity를 Response Body로 변환해 반환한다
return todo.toResponse()
}
flush()를 해준 다음에 Entity를 Response Body로 변환해서 반환하면 된다.
이제 잘 작동하는지 확인만 하면 된다.
이 글을 작성하는 지금 시간인 5월 16일 오후 8시 51분으로 Response Body 안에 있는 최종 수정 시간이 잘 나오는 것을 볼 수 있다.
그리고 또 하나 의문이었던 부분이 있었다. '수정을 하고 나서 페이지를 새로고침 하면 DB에서 어차피 값을 다시 불러오기 때문에 Response Body로 저렇게 모든 내용을 꼭 보내야 하는가'라고 생각해서 값을 수정한다고 Response Body를 저렇게 꼭 내보내야할까? 라는 의문이 있었다.
이 부분에 대해서도 의견을 구해보았는데, 페이지를 새로고침 하지 않고도 Response Body를 이용하여 페이지를 다시 구성해서 보여줘야할 수도 있기 때문에 Response Body가 필요하다고 하셨다. 상황에 따라서는 저런 Response Body가 필요하지 않을 수도 있겠지만, 필요한 경우에 저렇게 만들어서 응답을 보내줘야하기 때문에 잘 익혀두어야겠다는 생각이 들었다.
내일은 과제 하던 것을 모두 마무리할 수 있을 것 같다.
2. 오늘 배운 것
- Spring JPA에 대해서 조금 더 이해할 수 있었던 것 같다.
- 내일은 과제를 마무리하고 제출할 수 있을 것 같다.
'오늘 배운 것' 카테고리의 다른 글
24-05-18 알고리즘 문제 풀이 (0) | 2024.05.18 |
---|---|
24-05-17 Kotlin 범위 지정 함수 (0) | 2024.05.17 |
24-05-15 Spring 개인 과제 (3) (0) | 2024.05.15 |
24-05-14 Spring 개인 과제 (2) (0) | 2024.05.14 |
24-05-13 Spring 개인 과제 (0) | 2024.05.13 |