개선 전 코드

 

BidProductResponseDto가 생성될 때 경매 상품의 제시자가 아무도 없어 topBid가 null인 경우 NPE가 발생했다.

 


    public BidProductResponseDto(BidProduct bidProduct) {
        id = bidProduct.getId();
        name = bidProduct.getName();
        description = bidProduct.getDescription();
        startPrice = bidProduct.getStartPrice();
        expirationPeriod = bidProduct.getExpirationPeriod();
        feetSize = bidProduct.getFeetsize();
        footSize = bidProduct.getFootsize();
        footPicture = bidProduct.getFootpicture();
        brand = new BrandResponseDto(bidProduct.getBrand());

        topBid = new BidResponseDto(bidProduct.getTopBid());

        status = bidProduct.getStatus();

        createdAt = bidProduct.getCreatedAt();
        updatedAt = bidProduct.getUpdatedAt();
        for (int i = 0; i < bidProduct.getBids().size(); i++) {
            bidResponseDtoList.add(new BidResponseDto(bidProduct.getBids().get(i)));
        }
    }

 

 

해결방안

 

입찰이 하나도 없을 때 빈 객체를 생성한 뒤, topBid의 제시자는 경매상품 출품자로, topBid의 가격은 경매 시작가로 설정한다.

 


    public BidProductResponseDto(BidProduct bidProduct) {
        this.id = bidProduct.getId();
        this.name = bidProduct.getName();
        this.author = bidProduct.getUser().getName();
        this.description = bidProduct.getDescription();
        this.startPrice = bidProduct.getStartPrice();
        this.expirationPeriod = bidProduct.getExpirationPeriod();
        this.feetSize = bidProduct.getFeetsize();
        this.footSize = bidProduct.getFootsize();
        this.footPicture = bidProduct.getFootpicture();
        this.brand = new BrandResponseDto(bidProduct.getBrand());

        // topBid 설정 (경매 제시가가 아직 없을 경우 처리)
        if (bidProduct.getTopBid() != null) {
            this.topBid = bidProduct.getTopBid();
        } else {
            // topBid가 없을 때 topBid 제시자는 경매상품 등록자로, 가격은 startPrice로 설정
            this.topBid = new Bid();
            this.topBid.setUser(bidProduct.getUser());
            this.topBid.setBidPrice(bidProduct.getStartPrice());
        }


        this.status = bidProduct.getStatus();

        this.createdAt = bidProduct.getCreatedAt();
        this.updatedAt = bidProduct.getUpdatedAt();

        this.bidResponseDtoList = bidProduct.getBids().stream()
                .map(BidResponseDto::new)
                .sorted(Comparator.comparing(BidResponseDto::getBidPrice))
                .toList();

    }

 

 

고찰할 점 

@Table(name = "bidproduct")
public class BidProduct extends Timestamped{

	...
 
    /**
     * 연관관계 - Foreign Key 값을 따로 컬럼으로 정의하지 않고 연관 관계로 정의합니다.
     */
     
    @OneToMany(mappedBy = "bidProduct", cascade = CascadeType.REMOVE)
    private List<Bid> bids = new ArrayList<>();

    @OneToOne
    @JoinColumn(name = "topBid")
    private Bid topBid;
    
    ...
   
}

BidProduct와 topBid는 일대일 단방향 연관관계인데 topBid가 null인 경우를 (topBid의 price가 null인 경우, topBid의 user가 null인 경우 등등..) 메서드마다 매번 핸들링해줘야 했다. 아예 topBid의 초기값을 설정하는 게 더 나은 방법이었을까?

+ Recent posts