4

Let's say I have a book entity and a library entity (one library can have multiple books, but each book belongs to only one library). They are defined as follows:

public class Library { @Id private Long id; @OneToMany(mappedBy = "library") private List<Book> books = new ArrayList<>(); } 

and

public class Book { @Id private Long id; @ManyToOne @JoinColumn(name="FK_Library", nullable=false) private Library library; } 

I want to find all books which belong to a particular library. One way is to create a LibraryRepository as follows:

public interface LibraryRepository extends JpaRepository<Library, Long>{} 

Now I have findById(Long libraryId) method that returns a Library object with a List<Book> in it.

I was wondering if it is possible to create a BookRepository and declare a method named findByLibraryId(Long libraryId) and let hibernate query the Book table by the foreign key FK_Library, without performing any joins.

Something like this:

public interface BookRepository extends JpaRepository<Book, Long> { public List<Book> findByLibraryId(Long libraryId); } 

The above method findByLibraryId does perform join. I do not want it to perform a join, since all I want is find all rows which have library_id defined by foreign key relationship.

Also is the first method more preferable then second one?

4
  • 1
    Why exactly you need this ? You can do this using native query and may be using JPQL also Commented Aug 10, 2020 at 11:14
  • Using native query might bind it to specific type of schema. Commented Aug 10, 2020 at 11:17
  • Also, in findById method of LibraryRepository it returns Library object with List<Book>, but it does not perform join when I see the hibernate generated query. How is this possible? Commented Aug 10, 2020 at 11:19
  • 1
    @OneToMany by default lazy, so first fetch the library then fetch the books of the library in separte query when getter called. So 2 queries executed. Commented Aug 10, 2020 at 11:22

2 Answers 2

3

You can use @Query with JPQL to do that

@Query("SELECT b FROM Book b WHERE b.library.id = :libraryId") public List<Book> findByLibraryId(Long libraryId); 
Sign up to request clarification or add additional context in comments.

2 Comments

Looking from performance side, using @Query is better or using LibraryRepository's findById method?
Depends if you want only books of library then use @Query and if you want Library also then query in LibraryRepository and rather doing two query you do that using one query using @EntityGraph
2

You could change the @ManyToOne relationship to lazy loading.

@ManyToOne(fetch = FetchType.LAZY) 

This is the default for OneToMany, thats why you see no join when you search the Library.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.