티스토리 뷰
필자는 해당 기능을 구현하는 것 중에서 유저의 필드 중 특정 부분만 업데이트를 해주는 서비스가 있었습니다.
그래서 테스트케이스에서 응답에 대하여 해당 필드 값을 반환을 안해줘서 이에 대한 체크를 못했던 것이 컸던 것 같다.
변경 전 코드
@Transactional
public Message clickAlarmToggle(Account account, Boolean on) {
account.setIsAlarm(on);
return Message.of(StatusEnum.ACCOUNT_OK,AccountContent.CHANGE_ALARM_TOGGLE);
}
public static Account getAccount() {
PrincipalDetails principal = (PrincipalDetails) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
return principal.getAccount();
}
account 정보는 바로 위에 있는 util로 가져온다.
제가 기대했던 것은 on 에 따라 값이 바뀌는 것을 생각했는데 실제로는 그렇지 않았다.
그래서 필자는 다음과 같이 변경하였다.
@Transactional
public Message clickAlarmToggle(Account account, Boolean on) {
Account user = accountRepository.findByEmail(account.getEmail()).orElseThrow(NotFoundUserInformationException::new);
user.setIsAlarm(on);
return Message.of(StatusEnum.ACCOUNT_OK,AccountContent.CHANGE_ALARM_TOGGLE);
}
이렇게 다시 해당 정보로 조회를 하고 필드를 바꾼 다음에 더티 체킹을 하니깐 값이 변하는 것이었다.
스프링에 대해서 좀 더 다가가는 시간이었다.
강의를 듣다가 왜 그런지 알게되서 추가 글을 적어봅니다.
제가 처음에 느낀 문제에 대한 것을 `준영속 엔티티`라 합니다
이미 DB에 한 번 저장되어서 식별자가 존재한 것으로 기존 식별자를 가지고 있으면 준영속 엔티티라 한다.(영속성 컨테스트가 더 이상 관리하지 않는 것을 말한다.)
준영속 엔티티를 수정하는 2가지 방법
- 변경 감지 기능 사용 (dirty checking)
- 병합 사용(merge)
제가 위에서 해결한 방법은 변경 감지 기능 사용으로서 dirty checking이라고 말하기도 합니다.
병합을 사용하면 고려해야할 사항이 있습니다.
기존 데이터에서 추가된 것은 넣어주고 명시되지 않은 것은 null로 넣기 때문에 위험합니다. 그래서 update 관련 처리를 할 때에는 변경감지를 사용하시는 것을 권장합니다.
저는 컨트롤러 단에서 account에 대한 정보를 가져오는데 이 때 이 값을 조회용도로만 사용한다면 큰 문제는 없다. 하지만 서비스 레이어에 그 값을 줄 때에는 영속성 컨텍스트에서 관리하지 않는 대상이 되기 때문에 다시 그 유저에 대한 정보를 재조회를 통해 영속성 컨텍스트를 관리하게 해주고 그에 대한 변경 감지를 통해 필드 값 변경을 할 수 있게 된다.
- 컨트롤러에서 어설프게 엔티티를 생성하지 맙시다.
- 트랜잭션이 있는 서비스 계층에 식별자 id 와 변경할 데이터를 명확하게 전달합시다.
- 트랜잭션이 있는 서비스 계층에서 영속 상태의 엔티티를 조회하고, 엔티티의 데이터를 직접 변경합시다.
- 트랜잭션 커밋 시점에 변경 감지가 실행됩니다.
'JVM > Spring' 카테고리의 다른 글
[Spring] AOP (0) | 2022.04.05 |
---|---|
[Spring] @Transactional (0) | 2022.04.02 |
[JPA] JPA N+1 문제 (0) | 2021.12.03 |
[Spring Boot] Slack Bot 연동 작업 (0) | 2021.11.01 |
[Spring Boot] [Jpa] [PrePersist] default 값 설정하기 (0) | 2021.10.15 |
- Total
- Today
- Yesterday
- postgres
- django
- docker
- Pattern
- 면접
- Collections
- thread
- env
- 그래프
- 자바
- 알고리즘
- 카카오
- ubuntu
- Command Line
- 2021 KAKAO BLIND RECRUITMENT
- 프로그래머스
- Spring
- 파이썬
- BFS
- docker-compose
- PostgreSQL
- Linux
- 백준
- Java
- DRF
- dockerignore
- Celery
- Python
- headers
- setattr
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |