이번 챕터에서는 인증 체크와 JPA 의 더티 체킹을 활용하여 코드를 작성하였습니다.
1. 서비스 레이어 수정
public Board 게시글수정화면(int id, User sessionUser) {
        Board board = boardRepository.findById(id);
        if (board.getUser().getId() != sessionUser.getId()) {
            throw new Exception403("게시글 수정 권한이 없습니다.");
        }
        return board;
    }2. Controller 수정 화면 요청 처리
    @GetMapping("/board/{id}/update-form")
    public String updateForm(@PathVariable("id") int id, HttpServletRequest request) {
        User sessionUser = (User) session.getAttribute("sessionUser");
        if (sessionUser == null) {
            throw new Exception401("로그인 되지 않은 사용자입니다.");
        }
        Board board = boardService.게시글수정화면(id, sessionUser);
        request.setAttribute("model", board);
        return "board/update-form";
    }세션 체크를 서비스 레이어에서 수행하면 예상하지 못한 에러를 방지할 수 있습니다. 게시글 수정 전에는 반드시 인증을 확인해야 합니다.
게시글을 다 썼는데 확인 버튼을 누르고 나서야 로그인 하라며 페이지 이동 시키면…ㅠ
2.1 BoardRequest 내용 추가
    @Data
    public static class UpdateDTO {
        private String title;
        private String content;
    }이미 SaveDTO 가 있는데 굳이 UpdateDTO 를 만들어야 되나 생각할 수 있습니다.
요청메서드는 비슷하게 생겨도 중복 생성하기가 필요한 이유는
업데이트 부분의 일부만 변경하고자 하는 일이 생길 수 있기 때문이다.
3. 게시글 수정 로직(Service)
JPA 는 트랜잭션을 지원하는 쓰기지연을 통해
영속성 컨텍스트에 변경사항이 생길 때 마다 SQL 저장소에 SQL 을 생성 및 저장한다.
현재 변경 사항을 데이터베이스에 반영하는 것이 플러시이다.
    @Transactional
    public void 게시글수정(int id, BoardRequest.UpdateDTO updateDTO, User sessionUser) {
        // 1. 게시글 조회 (없으면 404)
        Board board = boardRepository.findById(id);
        // 2. 권한체크
        if (board.getUser().getId() != sessionUser.getId()) {
            throw new Exception403("게시글을 수정할 권한이 없습니다");
        }
        // 3. 게시글 수정
        board.setTitle(updateDTO.getTitle());
        board.setContent(updateDTO.getContent());
    }// flush() 자동 호출됨 (더티체킹)위의 코드는트랜잭션을 커밋하여 자동으로 플러시를 하는 방법입니다. 
현재 DB 와의 변경사항을 저장해야 하는 상황에서 flush() 를 호출하지 않은 채로 트랜잭션을 커밋해버리면 DB에 변경사항이 저장되지 않는 문제가 발생합니다. 
이를 방지하기 위해서 트랜잭션을 커밋할 때 자동으로 플러시가 호출됩니다. 
3.1 테스트코드 확인
    @Test
    public void updateByIdV2_test() {
        // given
        int id = 1;
        Board board = boardRepository.findById(id);
        // when
        board.setTitle("제목10");
        board.setContent("내용10");
        // 트랜잭션이 종료되면 flush()
        em.flush();
    }4. 컨트롤러 수정
    @PostMapping("/board/{id}/update")
    public String update(@PathVariable("id") int id, BoardRequest.UpdateDTO updateDTO) {
      
        User sessionUser = (User) session.getAttribute("sessionUser");
        if (sessionUser == null) {
            throw new Exception401("로그인 되지 않은 사용자입니다.");
        }
        boardService.게시글수정(id, updateDTO, sessionUser);
        return "redirect:/board/" + id;
    }매개변수가 변경되었다.
스프링부트 게시판 시리즈 v2 -1. https://inblog.ai/hj/27190 (User 테이블 생성 및 쿼리 수정) -2. https://inblog.ai/hj/27193 (User, Board 테이블 조인 과 JPQL) -3. https://inblog.ai/hj/27224 (회원 가입) -4. https://inblog.ai/hj/27225 DTO 를 통한 리팩토링 -5. https://inblog.ai/hj/27310 로그인, 로그아웃 -6. https://inblog.ai/hj/27316 서비스 레이어 추가 및 DTO 활용 -7. https://inblog.ai/hj/27430 예외처리 핸들러 설정과 User 서비스 리팩토링 -8. https://inblog.ai/hj/27431 Board 기능 리팩토링 -9. https://inblog.ai/hj/27560 게시글 수정, 더티체킹(flush) -10. https://inblog.ai/hj/27561 인터셉터, AOP 사용 / 마무리
Share article