Skip to content

Many to many relationship doesn’t add new Entity into the table

I have two entities Book and BookTag. They are connect by many to many relationship.

@Getter
@Setter
@Entity
@NoArgsConstructor
@AllArgsConstructor
@Builder(toBuilder = true)
@Table(name = "books")
public class Book {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "idbooks", insertable = false, updatable = false)
    private Long id;

   // other columns

    @ManyToMany(cascade = CascadeType.ALL)
    @JoinTable(
            name = "books_tags",
            joinColumns = {@JoinColumn(name = "book_id")},
            inverseJoinColumns = {@JoinColumn(name = "book_tag_id")}
    )
    Set<BookTag> tags = new HashSet<>();

    // getters and setters
}

@Getter
@Setter
@Entity
@NoArgsConstructor
@AllArgsConstructor
@Builder(toBuilder = true)
@Table(name = "book_tag")
public class BookTag {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id", insertable = false, updatable = false)
    private Long id;

    // other columns
 
    @ManyToMany(mappedBy = "tags")
    private Set<Book> books = new HashSet<>();

    // getters and setters
}

I try to add to the set of bookTags new BookTag entity using such service method

    public void updateBook(Book book, String tag) {

        if (tag != null && !tag.equals("")) {
            BookTag bookTag = bookTagService.findBookTagByTagName(tag).orElse(new BookTag(tag));
            Set<BookTag> allTags = book.getTags();
            allTags.add(bookTag);
            book.setTags(allTags);
        }

        bookRepository.save(book);
    }

But it doesn’t work, after I saved an entity into the mysql database it work correctly view of books_tags table after inserting a new tag to the book

After I try to add new tag to the book using the method above I get such result view of books_tags table after adding a new tag to the book

As you can see my method doesn’t add new entity, it changes an existing entry for a new bookTag ID. Help me please solve this question.

Answer

This line could actually return an unsaved Book tag: BookTag bookTag = bookTagService.findBookTagByTagName(tag).orElse(new BookTag(tag));

so call save on bookTag before adding it to the complete Book.