// Project 수정
@Transactional
public ProjectResponseDto updateProject(Long projectId, ProjectRequestDto requestDto, SessionUser sessionUser) {
Optional<UserProjectMapping> userProjectMapping = userProjectMappingRepository.findByUserIdAndProjectIdJoin(sessionUser.getUserId(),projectId);
if(!userProjectMapping.isPresent()){
throw new ApiRequestException("프로젝트에 참가한 사용자가 아닙니다.");
}else if(!userProjectMapping.get().getRole().equals(UserProjectRole.OWNER)){
throw new ApiRequestException("프로젝트 소유주가 아닙니다.");
}
Project project = userProjectMapping.get().getProject();
project.update(requestDto);
return ProjectResponseDto.fromEntity(project);
}
여기서는 예외와 조건을 따로 구분하지 않고 처리하였다는 것이다, 코드만 본다면 if 와 else if 모두 조건에 대한 처리로 보일수도있지 않을까 하는 생각이 들었다.
예외는 예외 답게, 조건은 조건 답게 처리 할 수 있는 방법을 생각해 보기로 하자!
// Project 수정
@Transactional
public ProjectResponseDto updateProject(Long projectId, ProjectRequestDto requestDto, SessionUser sessionUser) {
UserProjectMapping userProjectMapping = userProjectMappingRepository.findByUserIdAndProjectIdJoin(sessionUser.getUserId(), projectId);
// 예외처리
if(Objects.isNull(userProjectMapping)) {
throw new ApiRequestException("프로젝트에 참가한 사용자가 아닙니다.");
}
// 조건 처리(오너가 아니면 수정 불가)
if (!userProjectMapping.getRole().equals(UserProjectRole.OWNER)) {
throw new ApiRequestException("프로젝트 소유주가 아닙니다.");
}
Project project = userProjectMapping.getProject();
project.update(requestDto);
return ProjectResponseDto.fromEntity(project);
}
Optional을 쓰지 않고도 예외와 조건이 처리됨을 확인할수있다.
또 하나의 방법인 현재 여기서 findByUserIdAndProjectIdJoin 메소드는 Querydsl로 형성 되었다.
@Override
public UserProjectMapping findByUserIdAndProjectIdJoin(Long userId, Long projectId) {
return queryFactory
.select(userProjectMapping)
.from(userProjectMapping)
.join(userProjectMapping.project).fetchJoin()
.where(userProjectMapping.user.userId.eq(userId), userProjectMapping.project.projectId.eq(projectId))
.fetchFirst();
}
현재 userProjectMapping은 N-M 관계을 이어주는 하나의 Entity로서 , user 한 명이 project하나를 가지는 결과 값을 가지게 설정되었다.
@Override
public UserProjectMapping findByUserIdAndProjectIdJoin(Long userId, Long projectId) {
return Optional.ofNullable(queryFactory
.select(userProjectMapping)
.from(userProjectMapping)
.join(userProjectMapping.project).fetchJoin()
.where(userProjectMapping.user.userId.eq(userId), userProjectMapping.project.projectId.eq(projectId))
.fetchFirst())
.orElseThrow(() -> new ApiRequestException("프로젝트에 참가한 사용자가 아닙니다."));
}
// Project수정
@Transactional
public ProjectResponseDto updateProject(Long projectId, ProjectRequestDto requestDto, SessionUser sessionUser) {
UserProjectMapping userProjectMapping = userProjectMappingRepository.findByUserIdAndProjectIdJoin(sessionUser.getUserId(), projectId);
if (!userProjectMapping.getRole().equals(UserProjectRole.OWNER)) {
throw new ApiRequestException("프로젝트 소유주가 아닙니다.");
}
Project project = userProjectMapping.getProject();
project.update(requestDto);
return ProjectResponseDto.fromEntity(project);
}
모든 것이 정상적으로 작동한다.
그렇다면 무엇이 좋은 선택일까?
스타일의 차이라고 볼 수 있을 것 같다.
하지만 굳이 고르라고 한다면 예외처리는 query method 을 이용해 찾아올 때 부터 처리해서 가져와서 이후 불필요한 작업을 서비스단에서 하기 전에 예외가 발생하는 것이 낫다고 생각한다.