在复杂条件下使用JPA实体图
问题内容:
我有一个基于Spring MVC + JPA + Hibernate的项目。我正在使用实体图(JPA 2.1)定义要从数据库中获取哪些数据,如以下示例所示。
EntityGraph<Company> entityGraph = entityManager.createEntityGraph(Company.class);
entityGraph.addAttributeNodes("reviews");
Map<String, Object> hints = new HashMap<String, Object>();
hints.put("javax.persistence.loadgraph", entityGraph);
Company company = entityManager.find(Company.class, companyId, hints);
我的Review
实体与Company
实体(ManyToOne
)有关联。
在这里,我只是Company
使用填充的reviews
集合来获取对象。在上述情况下,此方法效果很好。但是,如果我想获取给定公司的全部或部分评论,该怎么办?也就是说,Review
与具有给定ID的公司关联的对象。我想要一个List<Review>
而不是带有的Company
对象List<Review>
。这只是一个例子-
基本上,我正在寻找比仅基于主键查找对象更大的灵活性。我可以毫无问题地使用HQL做到这一点,但是随后我将不得不编写几个类似的查询,具体取决于我在特定上下文中需要的数据。
上的find
方法javax.persistence.EntityManager
仅使基于主键查询对象成为可能。但是,是否可以在更复杂的场景中使用实体图,例如使用Criteria对象或HQL查询?例如,使用除主键之外的其他条件(甚至可能是关联条件)查找对象。
我希望我能说清楚。提前致谢!
问题答案:
您要查找的不是EntityGraph
s,而是JPA
Query
(a
NamedQuery
或a 形式的JPQL CriteriaQuery
)。这都是JPA规范的一部分。
所以基本上您可以:
- 注释每个实体
@NamedQueries
以指定JPQL查询。它们的优点是可以在部署时检查其语法(如果例如NamedQueries访问缺少的属性,则部署将失败)并且可重用,并且缺点是:它们是静态定义的(但是当然接受参数)。 - 使用EntityManager 在运行时JPQL查询上构造。由于上述优点,我比运行时查询更经常使用NamedQueries。
- 使用Criteria API具有优势,它们是类型安全的,因为您可以在真实的Java对象中加入/搜索/添加条件/对其进行播放。
关于EntityGraph
s:现在,它们只是一个帮助,因此可以从查询中获取其他字段(无论是否EntityManager.find()
与附加属性map参数或结合使用Query.setHints()
)。您也可以在更复杂的情况下使用子图。检查这个和这个例子。