인프런 커뮤니티 질문&답변
open-in-view값 true/false
작성
·
178
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
실행 방법과 순서는 첨부파일에 추가하였습니다.^^