작성
·
1.2K
5
안녕하세요. 스프링뉴비입니다.
양질의 강의로 JPA 학습을 잘 이어오고 있습니다.
다름이 아니라, 엔티티에서 변경감지에 대해 문득 궁금한 내용이 생겨 이렇게 질문 남겨드립니다.
흔히 엔티티에 롬복 @Setter 남기지 않고 코딩을 권장하고 있습니다. 불변성을 보장하고, 불필요한 사이트 이펙트를 해결하기 위해서라는 측면에서. 이 부분은 충분히 공감합니다.
첫 스프링 토이 프로젝트로 JPA에 대해 깊히 알지 못한 채, 엔티티 특정 값을 수정하기 위해 늘 Builder패턴으로 객체를 만들어 .save(Object) 로 해당 id를 조회해서 엎어치기를 했었는데요. 이번에 변경감지를 사용하고자 했더니, setter가 아니면 안되는 것 같더라구요.
혹시 더티체크를 불변성을 어느정도 보장할 수 있는 안전성있게 할 수 있는 방법이 있을까요? 저는 주로 생성자를 통해 불변성이 보장되는 Value Object 스럽게 써왔습니다.
JPA에서 더티체크를 위해서 setter를 설정해야된다는 것은 무조건일까요? 혹시 되도록 사이드이펙트가 일어나지 않도록 하는 또다른 방법은 없을까요? 더하여, 김영한강사님께서는 객체내에 setter라는 단어보다는 chageXX 이런식으로 하는 것을 권하셨던걸로 기억하는데, 혹시 맞을까요?
답변 3
16
안녕하세요 정규님^^ 좋은 질문입니다.
우선 엔티티는 변경이 필요하면 엔티티를 새로 생성하지 않고, 기존 엔티티를 조회해서 엔티티를 수정하는 방법을 사용하시는 것이 맞습니다.
제가 값 타입에서 설명한 불변성은 값 타입이라서 그런 것이고, 엔티티는 변경이 필요할 경우, 불변을 유지할 이유가 없습니다. 변경이라는 행위를 해도 식별자로 구별할 수 있기 때문이지요. 혹시라고 최초에 생성하고, 그 다음에 전혀 변경할 일이 없다면, 엔티티를 불변하게 설계해도 되지만, 그게 아니라면, setter나, changeXxx 같은 식으로 해당 엔티티를 직접 조회해서 변경하시는 것이 JPA가 의도한 설계입니다. 결국 엔티티를 변경할 때는 사이트이펙트가 일어나는 것이 JPA 설계 의도입니다. 이 의도에 따라서 변경하는 메서드를 주의깊게 잘 만드는 것이 중요합니다. (여기서 주의 깊게 라는 것이 setter 보다는 changeXxx 처럼 의미 있는 이름을 부여하는 것을 말합니다.)
그리고 더티체크를 위해서 setter를 사용하지 않고, changeXxx 같은 식으로 사용해도 엔티티 내부의 필드 값을 변경하면, 데티체크가 일어나고, 실제 UPDATE 쿼리가 실행됩니다.
함수형 스타일로 불변스럽게 사용하고 싶으신 마음은 이해가 됩니다. 그런데 JPA의 엔티티는 설계 당시부터 변경을 가정하고, 설계되었기 때문에, 말씀하신 방식으로 사용하기는 어렵고, 강제로 하더라도 JPA가 의도한 방식에 맞지 않습니다.
더티체크가 발생하지 않은 이유도, 조회한 엔티티를 직접 변경해야 더티체크가 일어납니다. 빌더를 통해 새로 엔티티를 생성하고 기존 엔티티를 변경하지 않으면, 이것은 JPA와 관계없는 완전 새로운 엔티티이기 때문에 더티체크가 발생하지 않습니다. 특히 기존 엔티티의 값이 변경되지 않았기 때문에, 당연히 더티체크가 발생하지 않습니다.
감사합니다^^
3
와.... 친절한 설명에 완-전 감동입니다🙇♀️ 감사합니다. 다음에 뵜는자리가 있더라면 진짜 부담안되는 초콜렛이라도 드리고 싶은 마음입니다!(강의 홍보 열심히 하겠습니다!!ㅋㅋㅋ)
0