[error] @Builder 애너테이션 사용시 NullPointerException 에러

2023. 11. 7. 16:45
728x90

 

Input은 이렇게 책 검색 정보 API 갖고 오고, 

Board의 정보도 같이 입력해서 폼 제출한 후, 각각의 엔터티에 저장시켜주려고 했다. 

 

엔터티는 이런 형식임

이때 외래키가 공유되므로 이미지 파일 올리면서 책 정보도 올리고 나눔글 정보까지 같이 올라가야만 한다. 

근데 각각의 외래키에 정보를 하나씩 넣기보다 한 테이블에서 입력을 하고 저장하면 다른 테이블에는 자동으로 올라갈 수 있도록

연관관계 메서드를 만들어서 넣는 것이 좋다!!

 

그래서 만든 연관관계 메서드는

Books 엔터티에 Image 추가 메서드,

// 연관관계 메서드
    // 이미지를 올리면 Books의 이미지리스트에 추가가 되면서 또 Images 엔티티에 추가가 된다.
    public void addImage(Images image) {
        imagesList.add(image);
        image.setBooks(this);
    }

 

Boards 엔터티에 Book 추가 메서드

    // 연관관계 메서드
    // 책 한 권을 올리면 Boards에 Book 추가되면서 Books엔티티에도 추가
    public void addBook(Books book) {
        book.setBoards(this);
        this.getBooksList().add(book);
    }

 

이렇게 만들어두고 service단에서 이 메서드를 불러들였다! 

 @Transactional
    public void uploadIntoDB(List<String> imgUrlList, InsertBookDTO bookDTO, InsertBoardDTO boardDTO) {
		
        // board로 메시지값 받아와서 build
        Boards boards = Boards.builder()
                .message(boardDTO.getMessage())
        		.build();
        
        // 그것을 DB에 저장
        Boards board = boardRepository.save(boards);
        
        // bookDTO에서 값을 받아와서 buiild
        Books books = Books.builder()
                        .title(bookDTO.getTitle())
                        .isbn(bookDTO.getIsbn())
                        .description(bookDTO.getDescription())
                        .author(bookDTO.getAuthor())
                        .publisher(bookDTO.getPublisher())
                        .pubdate(bookDTO.getPubdate())
                        .build();
		
       // 그 book 값을 board와 book에 함께 저장.
        boards.addBook(books);

	// 이미지 값을 urlList에서 각각 url로 저장 후 book에도 add
        for(String imgUrl : imgUrlList) {
            Images image = new Images();
            image.setImage_url(imgUrl);
            books.addImage(image);
        }
        // book값을 DB에 저장
        bookRepository.save(books);

    }

 

요렇게 해서 실행을 했는데..............

자꾸 null이라는 오류가 난다 ㅠㅡㅠ 

널친구는 항상 모때문인지 모르겠어서 어렵다 

NullPointerException

 

 

addBook에서 에러가 났다길래 그 엔터티가서 막 살펴봤지만 연관관계 잘 맺어있고,,,,,,,, 

뭐가 문젠지요....? 

또 폭풍 서치 그리고 짝꿍 찬스...

짝꿍도 해결 못하고 

혼자 또 찾아보다가

알아낸 것..............!!!!!!!!!!!!!!!!!

 

@Builder가 클래스에 사용될 때 npe가 난다는 것

이유는 build() 과정에서 포함되지 않은 필드들은 모두 null 또는 0이 된다고 한다. 

그래서 그럴 때에는 대신 default를 필드에 설정해주어야 한다는 것. (@Builder.Default로!!!) 

 

공식 문서 내용
@Builder.Default

If a certain field/parameter is never set during a build session, then it always gets 0 / null / false. If you've put @Builder on a class (and not a method or constructor) you can instead specify the default directly on the field, and annotate the field with @Builder.Default:
@Builder.Default private final long created = System.currentTimeMillis();

 

 

그래서 

Boards 엔터티에 Book 맵핑해준 것을 수정.

    @Builder.Default
    @OneToMany(
            mappedBy = "boards",
            cascade = CascadeType.ALL,
            orphanRemoval = true)
    private List<Books> booksList = new ArrayList<>();

 

그리고 Books 엔터티에 Image 매핑해준 것을 수정.

@Builder.Default
@OneToMany(
            mappedBy = "books", // mappedBy는 주인이 아님을 명시
            cascade = CascadeType.ALL)
            /* cascade옵션은 부모 엔티티에 대한 동작을 자식 엔티티로 전파할 때 사용됨.
             모든 영속성 동작(PERSIST, MERGE, REMOVE, REFRESH, DETACH)을 자식 엔티티로 전파하겠다는 의미.
             즉 부모엔티티에 대한 변경사항이 자식 엔티티에도 적용된다. */
    private List<Images> imagesList = new ArrayList<>();

 

이렇게 해주니까 

같은 builder를 써도 결국은 

 

요렇게 DB에 잘 들어갔다!!!!!!!!!!

예에ㅔㅔㅔㅔㅔㅔㅔ!!!!!

너무 힘겨웠다

1일 1오류 마주하기...ㅎㅎ

많이 배우는 중

728x90

BELATED ARTICLES

more