1. update-form 화면 연결
@GetMapping("/user/update-form")
public String updateForm() {
User sessionUser = (User) session.getAttribute("sessionUser");
if (sessionUser == null) throw new RuntimeException("인증이 필요합니다.");
// ViewResolver(view를 찾아줌)의 prefix에 /templates/라고 되어있기 때문. suffix = .mustache
return "user/update-form";
}2. 게시글 수정하기 전
1. 미리 화면에 들어있어야 하는 것
- username은 미리 입력되어 있어야 한다.
- username은 수정 불가능하므로 disabled를 통해 비활성해야 한다.
- password는 미리 입력되어 있으면 안된다.
- email은 미리 입력되어 있어야 한다.
2. 수정 가능한 것
- password와 email은 수정 가능하다.

3. 화면에 미리 뿌리기
- 기존의 방식대로 request로 담아서 화면에 뿌리는 것도 가능하다.
- 그러나 session에서 가져오면 굳이 request에 담을 필요 없이 가져올 수 있다.
- 이때 pw는 뿌리면 안되고 username 과 email만 가능하다.

3. 게시글 수정하기
1. UserRepository
- update를 위한 respository 메서드는 필요하지 않다.
- 유저 id로 조회하는 기능을 em.find를 통해 만든다.
public User findById(Integer id) {
return em.find(User.class, id);
}2. UserController
- 회원 정보 수정은 로그인한 유저만이 가능하므로 인증 체크를 해준다.
- update를 위해서는 updateDTO의 password와 email 그리고 update 쿼리의 where 절에 걸리게 되는 id를 session으로부터 받아 service로 넘긴다.
@PostMapping("/user/update")
public String update(UserRequest.UpdateDTO updateDTO) {
User sessionUser = (User) session.getAttribute("sessionUser");
if (sessionUser == null) throw new RuntimeException("인증이 필요합니다.");
// update user_tb set password = ?, email = ? where id = ?
User user = userService.회원정보수정(updateDTO, sessionUser.getId());
// 세션 동기화 (수정된 객체를 받아서 덮어씌운다)
session.setAttribute("sessionUser", user);
return "redirect:/";
}3. UserService
- 게시글을 findById 메서드에 의해 em.find로 찾게 된다.
- 이때 PC에 캐싱되지 않은 null인 경우 select문을 통해 DB에서 조회하게 된다.
- PC를 거쳐 DB에서 조회되면 객체는 영속화 된다.
- user 객체가 조회되지 않을 경우 없는 데이터를 굳이 업데이트할 필요가 없기 때문에 RuntimeException으로 미리 처리한다.
- null인 상태에서는 영속성 컨텍스트의 관리 대상이 아니므로 업데이트를 해도 의미가 없고 DB에 반영되지도 않는다.
- null 상태에서 수정한다는 것은 비영속 객체 즉 고립된 상태의 객체를 처리하고자 하는 것이다.
- 고립이란 더 이상 EntityManager가 관리하지 않는 객체를 의미한다.
더티체킹 : 더티한 것들을 PC에 놔둠 상태변경된 것들을 가지고 update 즉시 쿼리가 날라가는게 아니라 메서드가 종료될때 checking 이때 transactional이 안걸려있으면 select한다고 생각해서 update가 안됨
@Transactional
public User 회원정보수정(UserRequest.UpdateDTO updateDTO, Integer id) {
User user = userRespository.findById(id); // 조회됨 -> 영속화된 객체
if (user == null) throw new RuntimeException("회원을 찾을 수 없습니다."); // 없는 데이터를 업데이트할 필요 없음 (고립X)
user.update(updateDTO.getPassword(), updateDTO.getEmail()); // (PC를 거쳐서 DB에서 조회한)영속화된 객체의 상태가 변경된다.
return user;
} // 함수가 종료될 때 dirty checking -> 상태가 변경되면 update queryUser
// 회원정보 수정하는 의미있는 setter
public void update(String password, String email) {
this.password = password;
this.email = email;
}4. Dirty
Share article