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

윽이럴뚜가님의 프로필 이미지
윽이럴뚜가

작성한 질문수

실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발

변경 감지와 병합(merge)

book 객체가 왜 준영속인것인가

작성

·

827

17

수정을 시도하는 Book객체는 새로 만들어진것이잖아요 강사님.

이 Book객체는 이미 DB에 한번 저장이 되었다고 했는데 persist를 한적도 없고 db를 통해 find 한 객체도 아닌데 어떻게 이게 준영속 객체가 되는것이지요??????

단지 그냥 Book이란 객체를 만들고 set으로 평범한 값을 넣어줬을 뿐인데..

만약 set을 하고 em.persist(book) 을 해주면 뭐 영속성컨텍스트에 올라갈것이지만요...

그냥 book은 단순 객체가 아닌 이유를 이해하기가 정말 어렵습니다.ㅠ

기존식별자를 가지면 준영속이라고 하셨는데 book에 set을하여 id를 박는순간 이것은 준영속인것인가요? id는 식별자니까요

@PostMapping("items/{itemId}/edit")
public String updateItem(@ModelAttribute("form") BookForm form, @PathVariable String itemId) {

Book book = new Book();

book.setIsbn(form.getIsbn());
book.setAuthor(form.getAuthor());
book.setStockQuantity(form.getStockQuantity());
book.setPrice(form.getPrice());
book.setName(form.getName());
book.setId(form.getId());

itemService.saveItem(book);

return "redirect:/items";
}

답변 3

26

김영한님의 프로필 이미지
김영한
지식공유자

안녕하세요. 윽이럴뚜가님 좋은 질문입니다^^

저도 과거에 이 부분에 대해서 참 고민이 많았던 적이 있습니다.

정리해드리면, 준영속이라는 단어는 객체를 new 했거나, 안했거나를 기준으로 나누는 것은 아닙니다.

핵심은 식별자를 기준으로 영속상태가 되어서 DB에 저장된 적이 있는가로 보시면 됩니다.

그래서 식별자를 기준으로 이미 한번 영속상태가 되어버린 엔티티가 있는데, 더이상 영속성 컨텍스트가 관리하지 않으면 모두 준영속 상태입니다.

그게 em.detach()를 해서 직접적으로 준영속 상태가 될 수도 있고,

지금처럼 수정을 위해 html form에 데이터를 노출한 이후에 다시 new로 재조립된 엔티티일 수 도 있습니다.

심지어 다른 원격지 서버에 해당 엔티티를 네트워크로 전송할 수 도 있겠지요. 이 경우 원격지 서버에 도착한 엔티티는 영속성 컨텍스트에서 관리할 수 없기 때문에 준영속 상태라고 합니다. 그런데 생각해보면 원격지 서버에서 엔티티를 복구할 때도 내부에서는 new 라는 명령어를 사용하겠지요? 이때도 준영속 상태라고 합니다.

정말 과거 히스토리를 말씀드리면 ㅎㅎ EJB를 사용하던 시절에는 엔티티 객체를 다른 서버로 원격으로 전송할 수 있었습니다. 원격 서버로 전송하게 되면 원격 서버에 도착한 엔티티를 더는 관리할 수 없기 때문에 이때부터 준영속 상태라는 단어가 나오기 시작했습니다. (너무 오래전 일이라 정확하지 않을 수도 있습니다. ㅎㅎ)

new 상태인 객체와 준영속 상태의 객체는 merge()라는 명령에서 동작에 차이가 있습니다. new 상태인 객체는 merge()를 호출할 때 완전히 새로운 엔티티를 만듭니다. 반면에 준영속 상태의 엔티티는 DB에서 기존 엔티티를 찾고 그 값을 준영속 상태의 객체로 변경한 후에 반환합니다. 마치 준영속 상태의 객체가 영속 상태가 된 것 처럼요.

도움이 되셨길 바래요^^

안녕하세요! 영한쌤의 답변 중에 식별자를 기준으로 한다는 말씀이 헷갈립니다. 가령 id가 1인 book 엔티티가 DB에 저장된적이 있을때, 다른 new Book()로 생성한 bookChange 가 자신의 id값을 1로 설정하면, / id값이 동일한것뿐이지 영속성컨텍스트에는 없으므로 / 준영속 상태라는 것인가요?

그렇다면 강의에서 book이 준영속 객체인 이유는 단지 id가 영속상태였던 적이있는 엔티티의 id 값과 동일해서인건가요???

김영한님의 프로필 이미지
김영한
지식공유자

안녕하세요. 김지호님

네 기술적으로 보면 생각하신 부분이 맞습니다.

감사합니다.

5

"수정을 위해 html form에 데이터를 노출한 이후에 다시 new로 재조립된 엔티티일 수 도 있습니다"

와 JPA는 똑똑한 놈이군요... 상상이상입니다.

답변 감사합니다. 시원하게 풀렸네요

2

이렇게 되면 준영속과 일반 객체의 차이점에도 혼동이 올것 같군요.

준영속은 em.detach인가 뭔가 그거 해서 끊어버리면 준영속이 된다고 하셨던것 같네요 기본편에서(원래 영속이었는데 해제된것을 준영속이라고 하셨던거같음)

윽이럴뚜가님의 프로필 이미지
윽이럴뚜가

작성한 질문수

질문하기