Springboot/블로그만들기

[Springboot] 블로그 만들기 (12)_Update 테스트

21종 2023. 11. 24. 20:45

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;
}

 

결과확인

1번은 값이 깨졌기 때문에 2번으로 test

 

더티체킹이란 ? 이분이 정리를 넘 잘해두심..

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