Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to fetch EntityGraph dynamically in Spring Boot

I am developing an application using Spring Boot using JPA. In the application I am exposing a rest API. I do not want to use Spring data rest as I want to have full control of the data.

I am not able to figure out how to use EntityGraph dynamically.

Suppose I have following model taken from here

   @Entity
class Product {

  @ManyToMany
  Set<Tag> tags;

  // other properties omitted
}

interface ProductRepository extends Repository<Customer, Long> {

  @EntityGraph(attributePaths = {"tags"})
  Product findOneById(Long id);
}

I have following rest link to access Product http://localhost:8090/product/1

It returns to me a product with id 1

Questions:

  1. Will it by default fetch tags as we have mentioned @EntityGraph? If yes, then can this be configured on demand? Say, if in the query string I have include=tags, then only I want to fetch product with its tags.

I found this article but not sure how this can be of help.

like image 353
Ashwani K Avatar asked Nov 27 '15 12:11

Ashwani K


Video Answer


1 Answers

The definition of the EntityGraph in the Spring Data JPA Repository is static. If you want to have it dynamic you need to do this programatically like in the page you linked to:

EntityGraph<Product> graph = this.em.createEntityGraph(Product.class);
graph.addAttributeNodes("tags"); //here you can add or not the tags

Map<String, Object> hints = new HashMap<String, Object>();
hints.put("javax.persistence.loadgraph", graph);

this.em.find(Product.class, orderId, hints);

Also you can define the method with the EntityGraph in your JPA Repository.

interface ProductRepository extends Repository<Product, Long> {

@EntityGraph(attributePaths = {"tags"})
@Query("SELECT p FROM Product p WHERE p.id=:id")
Product findOneByIdWithEntityGraphTags(@Param("id") Long id);
}

And then have a method in your service which uses this method with the EntityGraph or the built in findOne(T id) without the EntityGraph:

Product findOneById(Long id, boolean withTags){
  if(withTags){
    return productRepository.findOneByIdWithEntityGraphTags(id);
  } else {
    return productRepository.findOne(id);
  }
}
like image 153
Robert Niestroj Avatar answered Sep 28 '22 06:09

Robert Niestroj