커머스 시스템에서 고객의 장바구니에 아이템을 넣는 서비스를 제작중 발생한 이슈에 대해서 작성해보겠습니다.
java.lang.NullPointerException: Cannot invoke "java.util.List.stream()" because "this.items" is null
문제확인
장바구니에 데이터를 상품의 데이터를 넣으려 하는데 잔여 수 보다 적은값을 입력했음에도, 정상적으로 동작하지 않고
NullPointerException 에러가 발생하였습니다.
[ 전자 제품 카테고리 ] 원하시는 상품 ID를 입력하세요.
상품 ID = 1 | 상품 이름 = Galaxy S25 | 상품 가격 = 1,200,000 | 잔여 갯수 = 100
상품 ID = 2 | 상품 이름 = iPhone 16 | 상품 가격 = 1,350,000 | 잔여 갯수 = 50
상품 ID = 3 | 상품 이름 = MacBook Pro | 상품 가격 = 2,400,000 | 잔여 갯수 = 100
상품 ID = 4 | 상품 이름 = AirPods Pro | 상품 가격 = 350,000 | 잔여 갯수 = 100
0 -> 뒤로가기
==================================
2
선택하신 상품을 장바구니에 넣을까요? 0: 뒤로가기 그외 숫자 : 장바구니에 넣을 숫자.
20
에러 발생. 다시 시도 해 주세요 = java.lang.NullPointerException: Cannot invoke "java.util.List.stream()" because "this.items" is null
private void shoppingProcess() {
showProductCategory();
try {
Optional<Product> selectedProduct = selectProduct();
selectedProduct.ifPresent(product -> {
System.out.println("선택하신 상품을 장바구니에 넣을까요? 0: 뒤로가기 | 그외 숫자 : 장바구니에 넣을 숫자.");
int quantity = sc.nextInt();
if (quantity == 0){
System.out.println("제품 추가 취소");
return;
}
//올바른 갯수를 입력했는지 확인
product.checkIsValidQuantity(quantity);
// 고객이 들고있는 카트에 아이템 추가
customer.cart.addItemToCart(product.getId(),product.getQuantity(),product.getName(),product.getPrice());
});
}catch (Exception e) {
System.out.println("에러 발생. 다시 시도 해 주세요 = " + e);
}
}
문제가 되는 메서드는
1. checkIsValidQuantity
2. addItemToCart
두 메서드 중 하나라고 추측하고 추적을 시작하였습니다.
해결과정
원인파악
1. checkIsValidQuantity 메서드를 먼저 보면 큰 로직없이 단순 수 비교 후 에러를 던지는 로직이고 기존 잔여량보다 많은 수를 입력시 해당 메서드에서 에러가 잘 발생하는것을 확인하여서, 문제가 없다고 판단하였습니다.
public void checkIsValidQuantity(int quantity) {
if(this.quantity < quantity) {
throw new IllegalArgumentException("현재 재고 수량보다 많은 수가 입력 되었습니다.");
}
}
2. addItemToCart 메서드를 살펴보면 findItemByProductId 을 옵셔널로 받아서 잘 nullpoint를 잘 방지했다고 생각을 했습니다.
public void addItemToCart(String productId, int quantity , String productName , int productPrice) {
//이미 저장된 데이터가 있는지 확인
Optional<CartItem> isCartItem = findItemByProductId(productId);
isCartItem.ifPresentOrElse(item -> {
// 있으면 기존 카트에 갯수만 추가.
// 새로운 객체 생성 X
item.manageProductQuantity(quantity);
}, //없으면 새로운 카트 아이템 추가
() -> items.add(new CartItem(productId,productName,productPrice,quantity)));
System.out.println("장바구니 추가 완료!");
}
그러나 에러 메세지를 자세히 살펴보면 Cannot invoke "java.util.List.stream()"because "this.items" is null
items 이 null이기 때문에 stream을 적용할 수 없다고 나옵니다. 그럼 findItemByProductId 안을 살펴보면
private Optional<CartItem> findItemByProductId(String productId) {
return items.stream().filter(i -> productId.equals(i.getProductId())).findFirst();
}
아 생각을 해보니 지금 고객은 처음 입장한 상태이고 카트에는 아무것도 없는데 items를 stream을 시도하려고해서 발생한 이슈구나..
아무것도 없으니 당연히 할 수 없지..
원인 수정
지금 코드를보면 변수를 선언만 해주고 실제로 생성자를 통해 만들어 주고있지 않다.
private final List<CartItem> items;
기본적으로 컬랙션의 경우 바로 객체를 필드에서 만들어 주도록 하자.
private final List<CartItem> items = new ArrayList<>();
결과
이젠 정상적으로 동작하는것을 확인 할 수 있었다!!
[ 주방 용품 카테고리 ] 원하시는 상품 ID를 입력하세요.
상품 ID = 17 | 상품 이름 = 반찬통 | 상품 가격 = 5,500 | 잔여 갯수 = 1
상품 ID = 18 | 상품 이름 = 트레이 세트 | 상품 가격 = 10,000 | 잔여 갯수 = 2
상품 ID = 19 | 상품 이름 = 바겐슈타이거 후라이펜 | 상품 가격 = 25,000 | 잔여 갯수 = 5
상품 ID = 20 | 상품 이름 = 바겐슈타이거 국자 | 상품 가격 = 13,500 | 잔여 갯수 = 10
0 -> 뒤로가기
==================================
18
선택하신 상품을 장바구니에 넣을까요? 0: 뒤로가기 | 그외 숫자 : 장바구니에 넣을 숫자.
1
장바구니 추가 완료!
이번 이슈를 통해 NullPointerException은 단순히 “값이 없다”가 아니라, “객체 자체가 존재하지 않는다”는 의미라는 점을 다시 한 번 체감했다.
장바구니에 아직 아무 상품도 담지 않은 상태는 List가 비어 있는 상태이지, List 자체가 null이어서는 안 된다는 사실을 간과하고 있었다.
'이슈' 카테고리의 다른 글
| [트러블 슈팅] spring swagger 버전 이슈 ControllerAdviceBean (0) | 2026.02.05 |
|---|---|
| [트러블 슈팅] "List.add()해도 추가되지 않는 이슈" - 불변 객체 건드리기. (1) | 2026.01.22 |
| 책임과 역할을 적절하게 분배하지 못한 이슈 (0) | 2026.01.21 |
| 제네릭에 extends Number를 해도 사칙연산이 안되는 이유 (0) | 2026.01.14 |
| Next.js 서버컴포넌트(SSR)에서 서버 통신시 쿠키 세팅 안됨이슈 (0) | 2025.12.16 |