DB
id가 1인 홍길동의 비밀번호를 5678로, email을 dddd로 변경하고 싶다.
Controller
// save 함수는 id를 전달하지 않으면 insert를 해주고
// save 함수는 id를 전달하면 해당 id에 대한 데이터가 있으면 update를 해주고
// save 함수는 id를 전달하면 해당 id에 대한 데이터가 없으면 insert 해준다.
// email, password 회원정보 수정
@PutMapping("/dummy/user/{id}")
public User updateUser(@PathVariable int id, @RequestBody User requestUser) { // Json 형식으로 된 데이터를 받을꺼임!! 그래서 RequestBody가 필요하다.
// json 데이터를 요청 => Java Object(MessageConverter의 Jackson 라이브러리가 변환해서 받아준다.
System.out.println("id : " + id);
System.out.println("password : " + requestUser.getPassword());
System.out.println("email : " + requestUser.getEmail());
requestUser.setId(id);
requestUser.setUserName("홍길동"); // userName의 제약조건에 notnull이 있기 때문에 값을 세팅해야된
userRepository.save(requestUser);
// save할때 id값을 넘겨줬을때 그 id값이 있다면 update 없으면 insert한다.
return null;
}
값을 넣어보자
email, password는 잘 바뀌었는데 다른 데이터가 전부 다 null로 세팅됐다.
그 이유는 쿼리가 아래와 같이 던져졌는데 createDate와 role값을 세팅하지 않아서 전부 null 값이 들어가게 된거다.
update
User
set
createDate=?,
email=?,
password=?,
role=?,
userName=?
where
id=?
해결방법
먼저 id가 1인 유저객체를 불러온후에 변경할 값으로 set 하고 그 유저객체로 save함수를 태워야한다.
@PutMapping("/dummy/user/{id}")
public User updateUser(@PathVariable int id, @RequestBody User requestUser) {
// Json 형식으로 된 데이터를 받을꺼임!! 그래서 RequestBody가 필요하다.
// Json 데이터를 요청 => Java Object(MessageConverter의 Jackson 라이브러리가 변환해서 받아준다.
System.out.println("id : " + id);
System.out.println("password : " + requestUser.getPassword());
System.out.println("email : " + requestUser.getEmail());
User user = userRepository.findById(id).orElseThrow(()->{ // id가 1인 유저의 정보
return new IllegalArgumentException("수정에 실패했습니다.");
});
user.setPassword(requestUser.getPassword());
user.setEmail(requestUser.getEmail());
userRepository.save(user);
// save할때 id값을 넘겨줬을때 그 id값이 있다면 update 없으면 insert한다.
return null;
}
이 방법말고 다른 방법이 있다.
@Transactional 어노테이션을 추가 , Save 함수 제거 -> 정상적으로 값이 변경된다. 이것을 더티 체킹이라고 한다.
@PutMapping("/dummy/user/{id}")
@Transactional
public User updateUser(@PathVariable int id, @RequestBody User requestUser) {
System.out.println("id : " + id);
System.out.println("password : " + requestUser.getPassword());
System.out.println("email : " + requestUser.getEmail());
User user = userRepository.findById(id).orElseThrow(()->{ // id가 1인 유저의 정보
return new IllegalArgumentException("수정에 실패했습니다.");
});
user.setPassword(requestUser.getPassword());
user.setEmail(requestUser.getEmail());
// userRepository.save(user);
// 더티 체킹이라고 함
return user;
}
결과확인
더티체킹이란 ? 이분이 정리를 넘 잘해두심..
https://velog.io/@_koiil/JPA-%EB%8D%94%ED%8B%B0-%EC%B2%B4%ED%82%B9-Dirty-Checking
[JPA] 더티 체킹(Dirty Checking)
샤라웃 투 더티체킹
velog.io
참고 유튜브 (메타코딩님 강의)
https://youtu.be/oijoJtiGPhI?si=xXX_2_bU9aVnrqkg