0

I am working on a small project using Spring Boot, Hibernate, and JPA. I have created three entities-

  1. Book
  2. Author
  3. Publication

Required relationships-

  1. One book can be written by multiple authors and the author can have many books. Therefore- Many to Many Relationship
  2. One book can have only one publication and one publication can have many books. Therefore- Many to One Relationship

The code for these entities-

  1. Book.java-
//...import statements

@Entity
@Data
public class Book {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "Book_id")
    private int id;

    @Column(name = "Book_name",nullable = false, unique = true)
    private String bookName;

    @Column(name = "Publication_date",nullable = false)
    @JsonFormat(shape=JsonFormat.Shape.STRING, pattern="yyyy-MM-dd")
    private Date publishDate;

    @Column(name = "ISBN",nullable = false, unique = true)
    private String isbn;

    @ManyToOne
    @JoinColumn(name = "publication_id", nullable = false)
    private Publication publication;

    @ManyToMany
    @JoinTable(name = "Book_Author", joinColumns = @JoinColumn(name = "book_id", referencedColumnName = "Book_id"), inverseJoinColumns = @JoinColumn(name = "author_id", referencedColumnName = "Author_id"))
    private Set<Author> authors = new HashSet<>();

}

  1. Author.java-
//... import statements

@Entity
@Data
public class Author {
    
    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    @Column(name="Author_id")
    private int id;

    @Column(name="First_name",nullable = false)
    private String firstName;
    @Column(name="Last_name",nullable = false)
    private String lastName;
    @Column(name="Mobile_number",nullable = false, unique = true,length = 10)
    private long mobileNo;

    @ManyToMany(mappedBy = "authors")
    Set<Book> books=new HashSet<>();
}

  1. Publication.java-
//... import statements
@Entity
@Data
public class Publication {
    
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int id;
    @Column(name="Publication_name",nullable = false,unique = true)
    private String name;

    @Column(name="Registration_number",nullable = false, unique = true)
    private String regNumber;

    @OneToMany(mappedBy = "publication")
    Set<Book> books=new HashSet<>();
}

Problems- I am facing following issues with the code:

  1. In the Many to Many relationship of Book and Author, when fetching Book or Author, I do not get the corresponding Author and Book respectively. What I get is an empty set. Example-
 @Override
    public BookDto getBook(int id) {
        Book book=this.bookRepository.findById(id).get();
        System.out.println("Book Publisher: "+book.getPublication());
        System.out.println("Author: "+book.getAuthors()); //empty set
        return this.bookToDto(book);
    }

Although, when I use SQL query in MySQL, I get the result-

Select * from demodb.book natural join demodb.book_author natural join demodb.author

Also, the Hibernate query shows that the query is being fired on the join of the tables to fetch data but nothing is returned in the query.
2. In the Many to One relationship of Book and Publication, when fetching Publication, the associated set of books is not fetched from the database, although Hibernate query is fired to fetch. But, when fetching a book, publication is fetched.

Query when fetching publication by id- (I am aware that cyclic dependency might occur but the objects are not fetched at all because I get empty Set in publication.getBooks())

Hibernate: 
    select
        p1_0.id,
        p1_0.publication_name,
        p1_0.registration_number
    from
        publication p1_0
    where
        p1_0.id=?
Hibernate: 
    select
        b1_0.publication_id,
        b1_0.book_id,
        b1_0.book_name,
        b1_0.isbn,
        b1_0.publication_date
    from
        book b1_0
    where
        b1_0.publication_id=?
Hibernate: 
    select
        b1_0.publication_id,
        b1_0.book_id,
        b1_0.book_name,
        b1_0.isbn,
        b1_0.publication_date
    from
        book b1_0
    where
        b1_0.publication_id=?
Hibernate: 
    select
        a1_0.book_id,
        a1_1.author_id,
        a1_1.first_name,
        a1_1.last_name,
        a1_1.mobile_number
    from
        book_author a1_0
    join
        author a1_1
            on a1_1.author_id=a1_0.author_id
    where
        a1_0.book_id=?
Hibernate: 
    select
        b1_0.author_id,
        b1_1.book_id,
        b1_1.book_name,
        b1_1.isbn,
        p1_0.id,
        p1_0.publication_name,
        p1_0.registration_number,
        b1_1.publication_date
    from
        book_author b1_0
    join
        book b1_1
            on b1_1.book_id=b1_0.book_id
    left join
        publication p1_0
            on p1_0.id=b1_1.publication_id
    where
        b1_0.author_id=?
Hibernate:
    select
        a1_0.book_id,
        a1_1.author_id,
        a1_1.first_name,
        a1_1.last_name,
        a1_1.mobile_number
    from
        book_author a1_0
    join
        book b1_1
            on b1_1.book_id=b1_0.book_id
    left join
        publication p1_0
            on p1_0.id=b1_1.publication_id
    where
        b1_0.author_id=?
  1. Error in using FetchType.LAZY in book-publication relationship-
    When I use fetch=FetchType.LAZY on the publication in Book entity and try to fetch book,
 @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "publication_id", nullable = false)
    private Publication publication;

I get the following error-

com.fasterxml.jackson.databind.exc.InvalidDefinitionException: No serializer found for class org.hibernate.proxy.pojo.bytebuddy.ByteBuddyInterceptor and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS) (through reference chain: com.ayushsingh.demojpa.dto.BookDto["publication"]->com.ayushsingh.demojpa.entity.Publication$HibernateProxy$F4hnTR8H["hibernateLazyInitializer"])

Note-
I am using ModelMapper 3.1.1, Dev Tools, Java version- 17 and Spring Boot Version- 3.0.6 .
I have clubbed these issues as they might be releated. Please help.

ayush
  • 464
  • 5
  • 17

0 Answers0