23.05.08 13:44 작성
·
198
0
회원을 수정하고, 회원의 닉네임이 중복되는 경우를 검증하고 싶었습니다. 더티체킹은 트랜잭션이 종료됐을 때 영속성 컨텍스트에서 변경된 것이 있는지 확인하고 변경된 것을 확인되면 업데이트 되는 것으로 알고 있는데요.
@Transactional
public void update(Long id, String name) {
Member member = findOne(id);
member.setName(name);
validateDuplicateMember(member);
}
private void validateDuplicateMember(Member member) {
// NullPointerException 발생 X
List<Member> findMembers = memberRepository.findByName(member.getName());
if (!findMembers.isEmpty()) {
throw new IllegalStateException("이미 존재하는 회원입니다.");
}
}
제가 의도한 목적은 다음과 같습니다.
회원을 조회 -> 영속성 컨텍스트 영속상태
회원 객체에 대한 이름을 변경 -> 트랜잭션 종료 시 더티체킹 예상
현재 객체 전달
전달 된 회원의 이름을 가진 회원을 조회
중복 시 Rollback, 아니라면 commit 후 더티체킹 이후 회원 엔티티 수정
하지만 중복이 아님에도 중복 예외가 발생하길래 log를 확인해본 결과
List<Member> findMembers = memberRepository.findByName(member.getName());
를 수행하기 전에 flush()가 되는 부분을 확인 할 수 있었습니다.
의심되는 부분은 4번에서 회원을 조회하는 과정에서 쿼리를 수행해야해서, 그 과정에서 쓰기 지연 저장소에 있던 쿼리들이 flush() 된 것이 아닌가 하는 의심이 듭니다.
그럼 제가 원하는 목적을 수행하기 위해서는 메서드를 아래와 같이 변경해야만 하는지..
@Transactional
public void update(Long id, String name) {
validateDuplicateMember(name);
Member member = findOne(id);
member.setName(name);
}
private void validateDuplicateMember(String name) {
// NullPointerException 발생 X
List<Member> findMembers = memberRepository.findByName(name);
if (!findMembers.isEmpty()) {
throw new IllegalStateException("이미 존재하는 회원입니다.");
}
}
다른 질문에서 중복 검증 시 영한님의 다음과 같은 답변을 확인 할 수 있었는데요.
@Transactional
public void update(Long id, String name) {
Member member = findOne(id);
validateDuplicateMember(member);
member.setName(name);
}
private void validateDuplicateMember(Member member) {
// NullPointerException 발생 X
List<Member> findMembers = memberRepository.findByName(member.getName());
if (!findMembers.isEmpty()) {
throw new IllegalStateException("이미 존재하는 회원입니다.");
}
}
이 부분은 변경되기 전이고 이미 등록된 상태의 Member를 가져오는 것이기 때문에 회원 이름 수정 시 중복 가능성에 대한 예외를 검증하는 것이 아니지 않나 하는 생각이 들어서 질문드립니다..!
2023. 05. 11. 15:31
감사합니다! 주 식별자가 아닌 컬럼으로 조회를 하게 되면 영속성 컨텍스트를 사용하지 않고 jpql이 사용된다는 부분도 얻어갈 수 있었네요! 이해되었습니다!