使用jpa api标准加入不相关的实体

时间:2013-06-14 10:29:29

标签: java jpa

两个数据库表具有外键关系。

它们被JPA映射到两个实体 A B ,但是从实体中手动删除了连接列,因此在JPA世界类中 A < / strong>与 B 无关,您无法通过字段/属性从一个导航到另一个。

使用条件api是否可以创建一个连接两个表的查询?

我在互联网上找到的所有示例都使用了连接列来实现目标,但是,如上所述,它已从代码中删除,因为大多数时候我对 A 之间的关系不感兴趣 B ,我担心可能的开销。

5 个答案:

答案 0 :(得分:20)

第一:外键关系不仅适用于导航。它们主要用于确保在关系中不引入虚假值。它们还可以帮助数据库进行查询优化。我建议你重新考虑一下。

无论如何,要创建使用多个不相关实体的查询,您需要将它们设置为fromroot)个实体(就像在SQL或JPQL中那样)

SELECT .... FROM Link l, Training t WHERE l.attribute = t.attribute;

Root<Link> rootLink = criteriaQuery.from(Link.class);
Root<Training> rootTraining = criteriaQuery.from(Training.class);
...
criteriaQuery.where(
    criteriaBuilder.equal(rootLink.get(link_.linkAttribute), trainingLink));

答案 1 :(得分:5)

加入不相关的实体不受最新JPA规范(2.1)

的保护

然而,Hibernate 5.1.0+和EclipseLink 2.4.0+支持ad hoc连接。 http://blog.anthavio.net/2016/03/join-unrelated-entities-in-jpa.html

另一种可能性是本机查询 http://www.oracle.com/technetwork/articles/vasiliev-jpql-087123.html

答案 2 :(得分:0)

正如我在this article中所述,自Hibernate 5.1起,您可以在使用JPQL和HQL时加入不相关的实体:

'Enter'

但是,此功能在Criteria API中不可用,因为这需要API扩展。

解决方案

尽管您可以尝试使用两个Tuple postViewCount = entityManager.createQuery( "select p as post, count(pv) as page_views " + "from Post p " + "left join PageView pv on p.slug = pv.slug " + "where p.title = :title " + "group by p", Tuple.class) .setParameter("title", "Presentations") .getSingleResult(); 对象并通过WHERE子句谓词模拟INNER JOIN,但生成的SQL并不是解决此问题的最佳方法。

您应该考虑使用jOOQ,因为除了使您能够以任何可能的方式联接表之外,如果将生成的SQL查询传递给JPA createNativeQuery方法,则还可以获取实体。

答案 3 :(得分:0)

您可以使用Blaze-persistence的JPA Criteria实现将其转换为JPQL / HQL,并提供该功能作为对JPA Criteria API的扩展。

在自述文件中查找“ Blaze-Persistence JPA-Criteria模块依赖项”:https://github.com/Blazebit/blaze-persistence/blob/master/README.md

然后使用BlazeCriteriaBuilder cb = BlazeCriteria.get(criteriaBuilderFactory),最后使用blazeCriteriaQuery.getCriteriaBuilder(entityManager)来呈现JPA Criteria Query对象。

答案 4 :(得分:0)

可以为连接查询创建视图并为此视图创建实体,并且 JpaRepository 可以像通常的表实体一样使用。 如果需要动态构建where-clause,在这个view-entity之上构建还是可行的