관리 메뉴

bright jazz music

[bootBoard] N:1(다대일) 연관관계: 9-5. 프로젝트 적용: 게시물 수정 처리 본문

Framework/Spring

[bootBoard] N:1(다대일) 연관관계: 9-5. 프로젝트 적용: 게시물 수정 처리

bright jazz music 2022. 10. 8. 22:07
  • 게시물 수정은 필요한 부분만 변경하고 BoardRepository.java의 save()를 이용해서 처리한다.
  • 게시물의 수정은 제목(title)과 내용(content)에 한해서 수정이 가능하도록 설정한다.
  • 수정을 위해서 Board클래스에 수정에 필요한 메서드를 추가한다.

 

1. 수정을 위한 Board 클래스 변경

Board.java

//Board.java
package com.example.bootboard.entity;

import lombok.*;

import javax.persistence.*;

@Entity
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Getter
@ToString(exclude = "writer")
public class Board extends BaseEntity{
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long bno;

    private String title;

    private String content;

    @ManyToOne(fetch = FetchType.LAZY) //명시적으로 Lazy Loading 지정
    private Member writer; //FK 연관관계 지정

    //Board클래스는 Member클래스의 email(PK)를 FK로 참조하는 구조이다.
    
    //수정을 위한 메서드 
    //제목 수정
    public void changeTitle(String title) {
        this.title = title;
    }
    //내용 수정
    public void changeContent(String content) {
        this.content = content;
    }
    
}

 

2. BoardService 인터페이스에 변경을 위한 메서드 modify() 선언

 

BoardService.java

//BoardService.java

package com.example.bootboard.service;

public interface BoardService {

	//등록 처리
    Long register(BoardDTO dto);

    //getList() : 목록처리
    PageResultDTO<BoardDTO, Object[]> getList(PageRequestDTO pageRequestDTO);

    //조회 처리
    BoardDTO get(Long bno);

    //게시글 삭제 기능
    void removeWithReplies(Long bno);

    //수정 처리
    void modify(BoardDTO boardDTO);

...

}

 

3. BoardServiceImpl에서 modify() 구현

BoardServiceImpl.java

 

modify()는 findById()를 이용하는 대신 LazyLoading을 사용하는 getOne()을 사용하려 했음.

그런데 getOne()이 depricated 되어서 아래와 같은 오류가 발생함

> Task :compileJava
Note: D:\personal\sts-personal-workspace\bootBoard\src\main\java\com\example\bootboard\service\BoardServiceImpl.java uses or overrides a deprecated API.

따라서 getOne() 대신 getById() 사용. (getById(): lazy loading, findById: eager loading)

아니 진짜... getById()도 depricated됨. 짜증...

 

최신인 getReferencedById() 사용...

 

//BoardServiceImpl.java

@Service
@RequiredArgsConstructor
@Log4j2
public class BoardServiceImpl implements BoardService {

    private final BoardRepository repository; // 자동 주입 final
    private final ReplyRepository replyRepository; //새롭게 추가

...

	//게시물 수정처리
    @Transactional
    @Override
    public void modify(BoardDTO boardDTO) {
    
        Board board = repository.getReferenceById(boardDTO.getBno());
        //getOne(), getById()는 depricated됨.
        
        board.changeTitle(boardDTO.getTitle());
        board.changeContent(boardDTO.getContent());

        repository.save(board);

    }

}

---------

원래는 @Transactional을 써주지 않아 아래와 같은 오류가 발생했었다.

아래의 포스팅을 참고하여 해결하였다.

 

[Spring Boot] 테스트 코드에서 getOne 또는 getById쓸 시 LazyInitializationException : could not initialize proxy - no

오류 메시지 원인 Hibernate에서 lazy loading을 사용하다보면 한 번쯤 직면할 수 있는 문제이다. (연관관계 매핑에서도 같은 오류가 발생할 수 있지만 여기서는 다루지 않겠다) 먼저 스프링 docs에서는

velog.io

 

4. Test

BoardServiceTests.java

//BoardServiceTests.java


@SpringBootTest
public class BoardServiceTests {

    @Autowired
    private BoardService boardService;


...    

//게시글 수정 처리 테스트
    @Test
    public void testModify(){
        BoardDTO boardDTO = BoardDTO.builder()
                .bno(3L) //bno가 3번인 녀석을 바꿀 거임
                .title("제목 변경합니다!!!!!!!!!!!")
                .content("내용 변경합니다!!!!!!!!!!!")
                .build();
        
        boardService.modify(boardDTO);
    }
    
}

 

수정 전 DB

 

5. 결과

콘솔 로그

 

2022-10-08 22:50:42.258  WARN 18380 --- [    Test worker] JpaBaseConfiguration$JpaWebConfiguration : spring.jpa.open-in-view is enabled by default. Therefore, database queries may be performed during view rendering. Explicitly configure spring.jpa.open-in-view to disable this warning
2022-10-08 22:50:42.811  INFO 18380 --- [    Test worker] c.e.bootboard.service.BoardServiceTests  : Started BoardServiceTests in 3.521 seconds (JVM running for 5.221)
Hibernate: 
    select
        board0_.bno as bno1_0_0_,
        board0_.moddate as moddate2_0_0_,
        board0_.reg_date as reg_date3_0_0_,
        board0_.content as content4_0_0_,
        board0_.title as title5_0_0_,
        board0_.writer_email as writer_e6_0_0_ 
    from
        board board0_ 
    where
        board0_.bno=?
Hibernate: 
    update
        board 
    set
        moddate=?,
        content=?,
        title=?,
        writer_email=? 
    where
        bno=?
2022-10-08 22:50:43.066  INFO 18380 --- [ionShutdownHook] j.LocalContainerEntityManagerFactoryBean : Closing JPA EntityManagerFactory for persistence unit 'default'
2022-10-08 22:50:43.066  INFO 18380 --- [ionShutdownHook] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Shutdown initiated...
2022-10-08 22:50:43.074  INFO 18380 --- [ionShutdownHook] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Shutdown completed.
BUILD SUCCESSFUL in 7s
4 actionable tasks: 3 executed, 1 up-to-date
오후 10:50:43: Task execution finished ':test --tests "com.example.bootboard.service.BoardServiceTests.testModify"'.

 

수정 후 DB

 

 

 

 

 

Comments