0

Hi I have a ManyToOne relationship between book and Student entity. I created this relationship as a bi-directional relationship. See classes below

Book class

@Getter
@Setter
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Entity(name = "Book")
@Table(name = "book")
public class Book {
    @Id
    @SequenceGenerator(
            name = "book_sequence",
            sequenceName = "book_sequence",
            allocationSize = 1
    )
    @GeneratedValue(
            strategy = GenerationType.SEQUENCE,
            generator = "book_sequence"
    )
    @Column(
            name = "id",
            updatable = false
    )
    private Long id;

    @Column(
            name = "book_name",
            nullable = false
    )
    private String bookName;

    @ManyToOne
    @JoinColumn(
            name = "student_id",
            nullable = false,
            referencedColumnName = "id",
            foreignKey = @ForeignKey(
                    name = "student_book_fk"
            )
    )
    private Student student;
}

Student class

@Getter
@Setter
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Entity(name = "Student")
@Table(name = "student",
        uniqueConstraints = {
            @UniqueConstraint(name = "student_email_unique", columnNames = "email")
        }
)
public class Student {
    @Id
    @SequenceGenerator(name = "student_seq", sequenceName = "student_seq", allocationSize = 1)
    @GeneratedValue(strategy = GenerationType.SEQUENCE,generator = "student_seq")
    @Column(name = "id",updatable = false)
    private Long id;

    @Column(name = "first_name", nullable = false, columnDefinition = "TEXT")
    private String firstName;

    @OneToMany(
            mappedBy = "student",
            orphanRemoval = true,
            cascade = { CascadeType.PERSIST, CascadeType.REMOVE }
    )
    private List<Book> books = new ArrayList<>();

    public void addBook(Book book){
//        if(books == null){
//             this.books = new ArrayList<>();
//        }
        if(!this.books.contains(book)){
            this.books.add(book);
            book.setStudent(this);
        }
    }

    public void removeBook(Book book){
        if(this.books.contains(book)){
            this.books.remove(book);
            book.setStudent(null);
        }
    }

    @Override
    public String toString() {
        return "Student{" +
                "id=" + id +
                ", firstName='" + firstName + '\'' +
                ", lastName='" + lastName + '\'' +
                ", email='" + email + '\'' +
                ", age=" + age +
                ", studentIdCard=" + studentIdCard.getCardNumber() +
                '}';
    }
}

When I run the application I am getting an error

Cannot invoke "java.util.List.contains(Object)" because "this.books" is null

This is available inside the addBook method in my student entity. In my student entity I initialized my books variable as below. I tried solutions provided in other similar issues raised in stackoverflow but unable to get this issue sorted.

@OneToMany(
            mappedBy = "student",
            orphanRemoval = true,
            cascade = { CascadeType.PERSIST, CascadeType.REMOVE }
    )
    private List<Book> books = new ArrayList<>();

I am not sure whether use of lombok has something to do with this. But if I write my code inside addBook method as below, issue is sorted

public void addBook(Book book){
        if(books == null){
             this.books = new ArrayList<>();
        }
        if(!this.books.contains(book)){
            this.books.add(book);
            book.setStudent(this);
        }
    }

Any ideas what might cause this issue?

Cheers

Shanka Somasiri
  • 581
  • 1
  • 8
  • 30

1 Answers1

0

I used the @Builder.Default annotation for the books variable.

@OneToMany(
            mappedBy = "student",
            orphanRemoval = true,
            cascade = { CascadeType.PERSIST, CascadeType.REMOVE }
    )
    @Builder.Default
    private List<Book> books = new ArrayList<>();

Reference - use Lombok @Builder @Default @Singular to initialise List<>

Shanka Somasiri
  • 581
  • 1
  • 8
  • 30