작성
·
93
0
@Controller
@RequiredArgsConstructor
@RequestMapping("/board")
public class BoardController {
@PostMapping("/update")
public String update(@ModelAttribute BoardDTO boardDTO, Model model) {
BoardDTO board = boardService.update(boardDTO);
model.addAttribute("board", board);
return "detail";
}
}
@Service
@RequiredArgsConstructor
public class BoardService {
private final BoardRepository boardRepository;
public BoardDTO findById(Long id) {
System.out.println("findById : "+ em.getDelegate());
// 이 아래 코드에서 질문 있습니다.
Optional<BoardEntity> optionalBoardEntity = boardRepository.findById(id);
if (optionalBoardEntity.isPresent()) {
BoardEntity boardEntity = optionalBoardEntity.get();
return BoardDTO.toBoardDTO(boardEntity);
} else {
return null;
}
}
public BoardDTO update(BoardDTO boardDTO) {
System.out.println("update : "+ em.getDelegate());
BoardEntity boardEntity = BoardEntity.toUpdateEntity(boardDTO);
boardRepository.save(boardEntity);
return findById(boardDTO.getId());
}
}
@MappedSuperclass
@EntityListeners(AuditingEntityListener.class)
@Getter
public class BaseEntity {
@CreationTimestamp
@Column(updatable = false)
private LocalDateTime createdTime;
@UpdateTimestamp
@Column(insertable = false)
private LocalDateTime updatedTime;
}
@Entity
@Getter @Setter
@Table(name = "board_table")
public class BoardEntity extends BaseEntity {
@Id GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String boardWriter;
private String boardPass;
private String boardTitle;
private String boardContents;
private int boardHits;
public static BoardEntity toUpdateEntity(BoardDTO boardDTO) {
BoardEntity boardEntity = new BoardEntity();
boardEntity.setId(boardDTO.getId());
boardEntity.setBoardWriter(boardDTO.getBoardWriter());
boardEntity.setBoardPass(boardDTO.getBoardPass());
boardEntity.setBoardTitle(boardDTO.getBoardTitle());
boardEntity.setBoardContents(boardDTO.getBoardContents());
boardEntity.setBoardHits(boardDTO.getBoardHits());
return boardEntity;
}
}
위에 코드 상황에서 open-in-view를 true로 하면 optionalBoardEntity에 createdTime 값이 null입니다.
제 생각으로는 open-in-view가 true 이므로 update()에서 (createdTime 값이 없는) boardEntity가 영속성 컨텍스트 1차 캐시에 존재하고, findById()에서 boardRepository.findById(id) 값을 호출하지만 1차캐시에 있는 값을 줘서 최종적으로 boardEntity값에는 createdTime값이 없는 것으로 이해했습니다.
그런데 왜 open-in-view값을 false로 하면 boardEntity에 createdTime 값이 있는지 모르겠습니다.
open-in-view가 true 이건 false 이건 영속성 컨텍스트 생존 범위에 Service는 포함되니 createdTime 값이 둘 다 없어야 되는것이 아닌지 궁금합니다.
답변 1
0
안녕하세요. lwisekiml님
우선 osiv 설정과 무관하게 항상 트랜잭션 안에서 엔티티를 조회하고 변경하는 방법을 고민하셔야 합니다.
서비스에서 업데이트 메서드를 다음과 같이 트랜잭션 안에서 엔티티를 조회하고, 변경 감지를 통해 변경한다면 원하는 결과를 확인하실 수 있을거에요.
@Transactional
public BoardDTO update(BoardDTO boardDTO) {
System.out.println("update : "+ em.getDelegate());
BoardEntity boardEntity = boardRepository.findById(boardDTO.getId()).get();
boardEntity.setBoardWriter(boardDTO.getBoardWriter());
boardEntity.setBoardTitle(boardDTO.getBoardTitle());
boardEntity.setBoardContents(boardDTO.getBoardContents());
return findById(boardDTO.getId());
}
감사합니다.
https://drive.google.com/file/d/1H0CJLp_dNX_jlm00iipeNtgYYwGwgeSF/view?usp=drive_link
실행 방법과 순서는 첨부파일에 추가하였습니다.^^