我正在使用JPA使用Spring Boot开发应用程序。 在应用程序中,我公开了一个rest API。我不想使用Spring数据休息,因为我想完全控制数据。
我无法弄清楚如何动态使用EntityGraph。
假设我有以下来自here
的模型 @Entity
class Product {
@ManyToMany
Set<Tag> tags;
// other properties omitted
}
interface ProductRepository extends Repository<Customer, Long> {
@EntityGraph(attributePaths = {"tags"})
Product findOneById(Long id);
}
我有以下休息链接访问产品 http://localhost:8090/product/1
它返回给我一个id为
的产品问题:
我找到了this条,但不确定这可能会有什么帮助。
答案 0 :(得分:7)
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);
您还可以在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);
}
然后在您的服务中有一个方法,它使用此方法与EntityGraph或内置findOne(T id)
而不使用EntityGraph:
Product findOneById(Long id, boolean withTags){
if(withTags){
return productRepository.findOneByIdWithEntityGraphTags(id);
} else {
return productRepository.findOne(id);
}
}
答案 1 :(得分:0)
您可以在存储库中执行此操作:
interface ProductRepository extends Repository<Customer, Long> {
Product findOneById(Long id);
@EntityGraph(attributePaths = {"tags"})
Product findOneWithTagsById(Long id);
}
并按照Robert Niestroj的建议创建服务方法。
答案 2 :(得分:0)
您可以使用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"));
请阅读文档以获取更多信息。
答案 3 :(得分:0)
您可以在下面添加一个实体图,确保该实体产品类与标记类有关联。
test.0.6.ppm