NULL update 이슈
NULL update 이슈란 데이터베이스 업데이트 작업 중에 NULL 값을 업데이트하려고 할 때 발생하는 문제를 의미합니다. 일반적으로 데이터베이스에서 NULL 값은 데이터가 존재하지 않음을 나타내기 위해 사용됩니다. 따라서 NULL 값을 업데이트하려는 시도는 데이터 무결성과 관련된 문제를 발생시킬 수 있습니다.
NULL update 이슈 사례
사진 게시판을 이용하는 사용자를 예시로 들어보겠습니다.
- 사용자가 사진 게시판 게시글 작성
- 제목, 내용, 사진 첨부 입력 후 작성 완료
- 사용자가 게시글 수정
- 수정 시 별도의 사진을 첨부하지 않으면 해당 파라미터 값이 NULL로 변경
- NULL값이 Controller → Service → DAO → DB까지 전달
이 상황은 사용자가 게시글을 수정할 때 항상 사진을 첨부해야 하므로 사용자 편의성이 떨어집니다.
@SessionAttributes
@SessionAttributes는 Spring 프레임워크에서 세션에 데이터를 저장하고 관리하는 데 사용되는 어노테이션입니다. 주로 컨트롤러 클래스나 메서드에서 세션에 데이터를 유지하고자 할 때 사용됩니다. @SessionAttributes를 사용하면 특정 모델 속성(attribute)을 세션에 저장할 수 있으며, 이 데이터는 세션에서 계속 유지되며 여러 HTTP 요청 간에 공유될 수 있습니다. Controller 단위로 사용하며 만약 NULL이면 View에서 가지고 있던 정보로 set을 해줍니다. 이때 View에 전달했던 정보로도 알려주어야 하기 때문에 @ModelAttribute 또한 함께 사용합니다.
BoardController.java
package com.spring.view.controller;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.SessionAttributes;
import org.springframework.web.multipart.MultipartFile;
import com.spring.biz.board.BoardService;
import com.spring.biz.board.BoardVO;
import com.spring.biz.member.MemberVO;
@Controller
@SessionAttributes("data")
public class BoardController {
@Autowired
private BoardService boardService;
@ModelAttribute("searchMap")
public Map<String,String> searchMap(){
Map<String,String> map=new HashMap<String,String>();
map.put("제목", "TITLE");
map.put("작성자", "WRITER");
return map;
}
@RequestMapping(value="/main.do")
public String main(@ModelAttribute("mem")MemberVO mVO, BoardVO bVO, Model model) {
System.out.println("searchCondition: "+bVO.getSearchCondition());
System.out.println("searchContent: "+bVO.getSearchContent());
if(bVO.getSearchCondition() == null) {
bVO.setSearchCondition("TITLE");
bVO.setSearchContent("");
} // 검색 로직에서 종종 활용되는 기법
mVO.setMid("test");
mVO.setMpw("1234");
// model.addAttribute("mem", mVO);
model.addAttribute("datas", boardService.selectAll(bVO));
return "main.jsp";
}
@RequestMapping(value="/board.do")
public String selectBoard(BoardVO bVO, Model model) {
model.addAttribute("data", boardService.selectOne(bVO));
boardService.update(bVO);
return "board.jsp";
}
@RequestMapping(value="/updateBoard.do")
public String updateBoard(BoardVO bVO) {
boardService.update(bVO);
return "board.do";
}
@RequestMapping(value="/deleteBoard.do")
public String deleteBoard(BoardVO bVO) {
if(boardService.delete(bVO)){
return "redirect:main.do";
}
else{
return "board.do";
}
}
@RequestMapping(value="/insertBoard.do", method=RequestMethod.GET)
public String insertBoardPage() {
// AOP 이전에는 일일히 로그를 직접 추가했었음
// 단순 페이지요청조차도 로그가 찍혔음
// 메서드 호출 == 느림
// service를 사용하는 건에 대해서만 AOP를 수행하기때문에,
// 로그가 안찍힘
// 메서드 안 호출 == 빠름
return "redirect:insertBoard.jsp";
}
@RequestMapping(value="/insertBoard.do", method=RequestMethod.POST)
public String insertBoard(BoardVO bVO) throws IllegalStateException, IOException {
MultipartFile fileUpload=bVO.getFileUpload();
if(!fileUpload.isEmpty()){
String fileName=fileUpload.getOriginalFilename();
System.out.println("파일명: "+fileName);
bVO.setFileName(fileName);
fileUpload.transferTo(new File("D:\\PJH\\ws\\day60\\src\\main\\webapp\\images\\"+fileName));
}
else {
bVO.setFileName("JJANGJJANGJ.png");
}
if(boardService.insert(bVO)){
return "redirect:main.do";
}
else{
return "redirect:insertBoard.jsp";
}
}
}
@SessionAttributes는 세션에 데이터를 저장하고 유지할 수 있습니다. 이를 통해 여러 HTTP 요청 간에 데이터를 공유하거나 임시 데이터를 보관할 수 있습니다. 또한 세션 관리를 위해 별도의 세션 객체를 생성하거나 관리할 필요가 없으므로 구현이 간단합니다.
하지만 세션은 서버 메모리를 사용하므로 세션에 저장되는 데이터가 크거나 많은 수의 사용자 세션을 관리해야 하는 경우 세션 오버헤드가 발생할 수 있으며 세션 데이터를 관리하고 유지하는 것은 서버 측에서 처리해야 하므로 서버 부하가 발생할 수 있습니다.
@SessionAttributes는 특정 상황에서 유용하지만, 데이터 공유와 관련된 다른 대안을 고려하고 애플리케이션의 요구 사항에 따라 적절한 데이터 관리 방식을 선택해야 합니다.
GitHub
https://github.com/Qkrwnsgus0522/Spring