작성
·
57
·
수정됨
0
31강에서 BookService 클래스에 강의와 똑같이 코드를 작성하였는데 실행하면 UserServiceV2 오류가 발생합니다.
UserRepository의 Optional<User> 형식을 받지 못해서 생기는 오류인 것 같은데, 어떻게 수정해야 하나요?
error: incompatible types: Optional<User> cannot be converted to User
User user = userRepository.findByName(name);
^
UserServiceV2.java
@Transactional
public void deleteUser(String name) {
//SELECT * FROM user WHERE name = ?
User user = userRepository.findByName(name);
if (user == null) {
throw new IllegalArgumentException();
}
userRepository.delete(user);
}
@Transactional
public void loanBook(BookLoanRequest request){
//1. 책 정보 가져오기
Book book = bookRepository.findByName(request.getBookName()).orElseThrow(IllegalArgumentException::new);
//2. 대출 기록 정보 확인하여 대출 중인지 확인
//3. 대출 중이면 예외 발생
if(userLoanHistoryRepository.existsByBookNameAndIsReturn(book.getName(), false)){
throw new IllegalArgumentException("진작 대출되어 있는 책입니다.");
}
//4. 유저 정보 가져오기
User user = userRepository.findByName(request.getUserName())
.orElseThrow(IllegalArgumentException::new);
//5. 유저 정보와 책 정보 기반 UserLoanHistory 저장
userLoanHistoryRepository.save(new UserLoanHistory(user.getId(), book.getName()));
}
package com.group.libraryapp.domain.user;
import org.springframework.data.jpa.repository.JpaRepository;
import java.util.Optional;
public interface UserRepository extends JpaRepository<User, Long> {
Optional<User> findByName(String name);
}
우선 오류를 없애기 위해 UserRepository에서 Optional을 빼고 null처리를 하도록 수정하였는데, 실행 시 오류는 없지만 웹UI로 테스트하면 서버 내부 오류가 발생했다고 뜹니다. 어떻게 수정해야 제대로 처리되는지 모르겠습니다.
추가로 이렇게 수정하였을 때, 이후 코드를 작성할 때 Optional 형식이 아니어서 발생하는 다른 오류가 없는지도 궁금합니다.
package com.group.libraryapp.domain.user;
import org.springframework.data.jpa.repository.JpaRepository;
import java.util.Optional;
public interface UserRepository extends JpaRepository<User, Long> {
User findByName(String name);
}
@Transactional
public void loanBook(BookLoanRequest request){
//1. 책 정보 가져오기
Book book = bookRepository.findByName(request.getBookName()).orElseThrow(IllegalArgumentException::new);
//2. 대출 기록 정보 확인하여 대출 중인지 확인
//3. 대출 중이면 예외 발생
if(userLoanHistoryRepository.existsByBookNameAndIsReturn(book.getName(), false)){
throw new IllegalArgumentException("진작 대출되어 있는 책입니다.");
}
//4. 유저 정보 가져오기
User user = userRepository.findByName(request.getUserName());
if(user == null){
throw new IllegalArgumentException();
}
//5. 유저 정보와 책 정보 기반 UserLoanHistory 저장
userLoanHistoryRepository.save(new UserLoanHistory(user.getId(), book.getName()));
}
UserServiceV2.java
@Transactional
public void deleteUser(String name) {
//SELECT * FROM user WHERE name = ?
User user = userRepository.findByName(name);
if (user == null) {
throw new IllegalArgumentException();
}
userRepository.delete(user);
}
답변 1
0
안녕하세요! 🙂 질문 주셔서 감사합니다.
하나씩 말씀드려 보면.. 먼저
UserRepository의 Optional<User> 형식을 받지 못해서 생기는 오류인 것 같은데, 어떻게 수정해야 하나요?
는 추측해주신 내용이 맞습니다.
User user = userRepository.findByName(name);
라는 코드가 있을 때 findByName()
이 Optional<User>
를 반환한다면, User 타입이 아닌 Optional<User>
로 받아야 합니다.
혹은 아예 findByName()이 User
를 반환하게 하고, 서비스 단에서 null check를 해줘도 괜찮고요!
추가로 이렇게 수정하였을 때, 이후 코드를 작성할 때 Optional 형식이 아니어서 발생하는 다른 오류가 없는지도 궁금합니다.
Optional은 객체 타입만 봤을 때 이 타입이 nullable (null이 들어갈 수 있는지) 한지, non-nullable 한지 알기 어렵다 보니 탄생한 객체로, Optional 로 감싸진 Optioan<T>
는 null이 들어갈 수 있다는 것을 보여줄 뿐, Optional
을 사용하지 않는다고 해서 추후 다른 오류가 생기지는 않습니다.
또한
실행 시 오류는 없지만 웹UI로 테스트하면 서버 내부 오류가 발생했다고 뜹니다. 어떻게 수정해야 제대로 처리되는지 모르겠습니다.
같은 경우는 웹 UI로 API를 호출 했을 때 '어떤 서버 내부 오류'가 발생한 건지 에러 로그를 보면 조금 더 자세히 말씀드릴 수 있을 것 같습니다. 🙂
자세한 상황과 함께 질문 남겨주셔서 감사드리고, 오류 로그는 올려주시면 한 번도 봐보겠습니다!
woddnjs님의 BE 개발 공부를 응원합니다. 🔥 감사합니다!
네네 아래 코드와 같이 사용하셔도 괜찮습니다.
그래도 왜 아래 코드는 되고 위의 코드는 에러가 발생하는지 그 원리를 아시면 좋을 것 같은데요! 그 이유는 Optional<User>
와 User
는 다른 타입이기 때문에 그렇습니다.
예를 들어 아래 함수를 생각해보죠
public void printList(List<Integer> numbers) {
for (int num : numbers) {
// num 출력
}
}
이 함수에
printList(Set.of(1, 2, 3));
이라는 코드를 사용할 수 있을까요? 없을까요?
정답은, 에러가 발생합니다. 왜냐하면 Set<Integer>
와 List<Integer>
는 다른 타입이기 때문이죠. 마찬가지로 xxxRepository.delete(?)
는 Entity인 User
같은 타입이 들어와야 하는데 Optional<User>
는 User
와 다른 타입 이기 때문에 에러가 발생하게 됩니다.
또 진행하시면서 어려운 점 있으시면 편하게 질문 남겨주세요~ 감사합니다! 🙇
감사합니다!
UserServiceV2를
이렇게 변경하였더니 delete에서 user를 사용하지 못하는 오류가 뜨는데,
그 다음 강의(34강)에 아래와 같은 코드가 나와서 그 코드대로 작성하였더니 오류 없이 실행이 가능한데, 이렇게 사용해도 되는 걸까요?