Lukasz Birski
Lukasz Birski

Reputation: 25

Problem with deleting entity from relational database

I am trying to write a method that would remove an entity from the table book that has a relation with entities from table comments. The idea is to remove all the records in comments while removing record in book.

Can someone help me with this? I don't know what is wrong, it is removing comments correctly but then error occurs. The method from service responsible for deleting, classes and message from Spring are below. Cheers

Error is as below:

Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.orm.jpa.JpaObjectRetrievalFailureException: Unable to find birski.bookstore.models.Comment with id 1; nested exception is javax.persistence.EntityNotFoundException: Unable to find birski.bookstore.models.

Comment with id 1] with root cause

Method from service responsible for deleting entities

    public ResponseEntity<?> deleteBookDto(String bookTitle){
        return bookRepository.findByTitle(bookTitle).map(b ->{
            for (Comment comment : b.getComments()){
                commentRepository.delete(comment);
            }
            bookRepository.delete(b);
            return new ResponseEntity<>("Book titled: " + bookTitle + " was deleted!", HttpStatus.OK);
        }).orElseThrow(()-> new ResourceNotFoundException("Book titled: " + bookTitle + " have not been found."));
    }

Book class

@Entity
@Table(name = "books", schema = "public")
public class Book {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @NotBlank(message = "Title is required")
    private String title;

    @NotBlank(message = "Author is required")
    private String author;

    @OneToMany(fetch = FetchType.EAGER, mappedBy = "book")
    @OnDelete(action = OnDeleteAction.CASCADE)
    private Set<Comment> comments = new HashSet<>();

    public Book() {
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getAuthor() {
        return author;
    }

    public void setAuthor(String author) {
        this.author = author;
    }

    public Set<Comment> getComments() {
        return comments;
    }

    public void setComments(Set<Comment> comments) {
        this.comments = comments;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }
}

Comment class

@Entity
@Table(name = "comments", schema = "public")
public class Comment {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @NotNull
    private String author;

    @NotNull
    private String description;

    @NotNull
    private float rating;

    @NotNull
    @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd")
    private Date date;

    @ManyToOne//(cascade = CascadeType.ALL)
    private Book book;

    public Comment() {
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getAuthor() {
        return author;
    }

    public void setAuthor(String author) {
        this.author = author;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public float getRating() {
        return rating;
    }

    public void setRating(float rating) {
        this.rating = rating;
    }

    public Date getDate() {
        return date;
    }

    public void setDate(Date date) {
        this.date = date;
    }

    public Book getBook() {
        return book;
    }

    public void setBook(Book book) {
        this.book = book;
    }
}

Upvotes: 0

Views: 699

Answers (1)

Jelaby
Jelaby

Reputation: 1198

You have

@OneToMany(fetch = FetchType.EAGER, mappedBy = "book")
@OnDelete(action = OnDeleteAction.CASCADE)
private Set<Comment> comments = new HashSet<>();

as well as your code to explicitly delete() your comments. When Hibernate handles deleting the the book, it tries to delete the book's comments, but you have already deleted those comments from the database. You need one or the other.

Upvotes: 1

Related Questions