I have two models - Product and Category. There is a relation between them - m:n. How I defined the relation at the Product side:
@JoinTable(
name = "products_categories",
joinColumns = @JoinColumn(
name = "product_id",
referencedColumnName = "id"
),
inverseJoinColumns = @JoinColumn(
name = "category_id",
referencedColumnName = "id"
)
)
@ManyToMany(fetch = FetchType.EAGER)
private Set<Category> categories;
When I try to load only one record ( findById
) it sends only one SQL Query and it's what I want to achieve. But when I request to load more than one it sends different SQL Query for every single product. How can I fix that problem? Should I write my own SQL Query (using EntityManager)?
Using EntityManager
you can use LEFT JOIN FETCH
to overcome the SELECT N+1 issue.
@Autowired EntityManager entityManager;
@Test
public void findWithEntityManager() {
Query q = entityManager.createQuery("SELECT p FROM ProductEntity p LEFT JOIN FETCH p.categories");
List<ProductEntity> prods = q.getResultList();
prods.forEach(p -> {
System.out.println(p.getCategories().size());
});
}
//Hibernate: select productent0_.id as id1_4_0_, ... from product productent0_ left outer join product_category categories1_ on productent0_.id=categories1_.ProductEntity_id left outer join category categoryen2_ on categories1_.categories_id=categoryen2_.id
===EDIT===
Strangely enough, using the same query with @Query
returning Page<T>
results in exception:
@Query("SELECT p FROM ProductEntity p LEFT JOIN FETCH p.categories c")
Page<ProductEntity> findAllLeftJoin(Pageable pageable);
// Caused by: org.hibernate.QueryException: query specified join fetching, but the owner of the fetched association was not present in the select list ...
However using a List<T>
it works fine but then I need to handle pagination manually.
@Query("SELECT p FROM ProductEntity p LEFT JOIN FETCH p.categories c")
List<ProductEntity> findAllLeftJoin();
// Hibernate: productent0_.id as id1_4_0_,... from product productent0_ left outer join product_category categories1_ on productent0_.id=categories1_.ProductEntity_id left outer join category categoryen2_ on categories1_.categories_id=categoryen2_.id
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.