How to Extract EntityGraph Dynamically in Spring Download

I am developing an application using Spring Boot using JPA. In the application, I set the rest API. I do not want to use Spring data, because I want to have full control over the data.

I cannot figure out how to use EntityGraph dynamically.

Suppose I have the 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 the following link to access the product http: // localhost: 8090 / product / 1

It returns me a product with identifier 1

Questions:

  1. Will it retrieve tags by default , as we mentioned @EntityGraph? If so, can this be configured on demand? Let's say if I have include = tags in the query string, then only I want to get the product with its tags.

I found this article but am not sure how this might help.

+5
source share
4 answers

The definition of EntityGraph in the JPA Spring data repository is static. If you want it to be dynamic, you need to do it programmatically, like on 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); 

You can also define a method with 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 you have a method in your service that uses this method with EntityGraph or inline findOne(T id) without EntityGraph:

 Product findOneById(Long id, boolean withTags){ if(withTags){ return productRepository.findOneByIdWithEntityGraphTags(id); } else { return productRepository.findOne(id); } } 
+7
source

You can do this in the repository:

 interface ProductRepository extends Repository<Customer, Long> { Product findOneById(Long id); @EntityGraph(attributePaths = {"tags"}) Product findOneWithTagsById(Long id); } 

and create a service method, as suggested by Robert Nistroy.

0
source

You can select EntityGraph at runtime using Spring Data JPA EntityGraph .
The setup is pretty simple:

  • Add: implementation 'com.cosium.spring.data:spring-data-jpa-entity-graph:2.0.7' to build.gradle
  • Add: @EnableJpaRepositories(repositoryFactoryBeanclass= EntityGraphJpaRepositoryFactoryBean.class) below @SpringBootApplication

Now you can choose the best EntityGraph at runtime. Example (this is an example from Spring Data JPA EntityGraph ):

 // This will apply 'Product.brand' named EntityGraph to findByLabel productRepository.findByLabel("foo", EntityGraphs.named("Product.brand")); // This will apply 'Product.supplier' named EntityGraph to findByLabel productRepository.findByLabel("foo", EntityGraphs.named("Product.supplier")); // This will apply 'supplier' attribute paths EntityGraph (don't need to define named EntityGraph) to findByLabel productRepository.findByLabel("foo", EntityGraphUtils.fromAttributePaths("supplier")); 

Please read the document for more information.

0
source

You can add an Entity graph as shown below, make sure the Entity product class is related to the tag class.

 @EntityGraph(attributePaths = { "tags" }) @Query( value = "select product from product) List<Product> findAllProduct(); 
0
source

Source: https://habr.com/ru/post/1236963/


All Articles