如何在Spring Boot中动态获取EntityGraph

Ash*_*i K 5 java spring jpa spring-data spring-data-jpa

我正在使用JPA使用Spring Boot开发应用程序.在应用程序中,我公开了一个rest API.我不想使用Spring数据休息,因为我想完全控制数据.

我无法弄清楚如何动态使用EntityGraph.

假设我从这里采取了以下模型

   @Entity
class Product {

  @ManyToMany
  Set<Tag> tags;

  // other properties omitted
}

interface ProductRepository extends Repository<Customer, Long> {

  @EntityGraph(attributePaths = {"tags"})
  Product findOneById(Long id);
}
Run Code Online (Sandbox Code Playgroud)

我有以下休息链接访问产品 http:// localhost:8090/product/1

它返回给我一个id为1的产品

问题:

  1. 默认情况下是否会像我们提到的那样提取标签 @EntityGraph?如果是,那么可以按需配置吗?比如说,如果在查询字符串中我有include = tags,那么我只想用其标签获取产品.

我找到了这篇文章,但不确定这有多大帮助.

Rob*_*roj 11

Spring Data JPA Repository中EntityGraph的定义是静态的.如果你想让它动态化,你需要以编程方式执行此操作,就像在链接到的页面中一样:

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);
Run Code Online (Sandbox Code Playgroud)

您还可以在JPA存储库中使用EntityGraph定义方法.

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);
}
Run Code Online (Sandbox Code Playgroud)

然后在你的服务中有一个方法,它使用这个方法与EntityGraph或findOne(T id)没有EntityGraph 的内置:

Product findOneById(Long id, boolean withTags){
  if(withTags){
    return productRepository.findOneByIdWithEntityGraphTags(id);
  } else {
    return productRepository.findOne(id);
  }
}
Run Code Online (Sandbox Code Playgroud)


bin*_*eat 8

您可以在运行时通过使用Spring Data JPA EntityGraph 选择 EntityGraph
设置非常简单:

  • 添加:implementation 'com.cosium.spring.data:spring-data-jpa-entity-graph:2.0.7'到 build.gradle
  • 添加:@EnableJpaRepositories(repositoryFactoryBeanClass = EntityGraphJpaRepositoryFactoryBean.class)波纹管@SpringBootApplication

现在,您可以在运行时选择最佳 EntityGraph。示例(这是来自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"));
Run Code Online (Sandbox Code Playgroud)

请阅读文档以获取更多信息。