How to join unrelated entities with the JPA Criteria API

放肆的年华 提交于 2020-01-21 02:40:09

问题


Two database tables have a foreign key relationship.

They are mapped to two entities A and B by JPA, but the join columns are manually removed from the entities, so in JPA world classes A and B are not related and you cannot navigate from one to the other through a field/property.

Using the JPA Criteria API, is it possible to create a query which joins the two tables?

All examples I found on internet uses the join column to achieve the goal, but, as stated above, it was removed from the code because most time I'm not interested in the relationship between A and B and I'm afraid about possible overhead.


回答1:


First: Foreign key relationship are not only for navigating. They mainly serve to ensure that no spurious values are introduced in the relationship. They also may help the database for query optimization. I would advise you to reconsider that.

Anyway, for creating a query that uses several unrelated entities, you need to put them as from (root) entities (as you would do in SQL or 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));



回答2:


Join on unrelated entities is not covered by latest JPA spec (2.1)

However Hibernate 5.1.0+ and EclipseLink 2.4.0+ support ad hoc joins. http://blog.anthavio.net/2016/03/join-unrelated-entities-in-jpa.html

Another possibility is native query http://www.oracle.com/technetwork/articles/vasiliev-jpql-087123.html




回答3:


As I explained in this article, since Hibernate 5.1, you can join unrelated entities when using JPQL and HQL:

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();

However, this feature is not available in Criteria API, as that would require an API extension.

The solution

While you could try to use two Root objects and emulate the INNER JOIN via WHERE clause predicates, the resulting SQL is not the best way to solve this issue.

You should consider using jOOQ as, besides giving you the ability to join tables in any possible ways, you can also fetch entities if you pass the generated SQL query to the JPA createNativeQuery method.




回答4:


You could use the JPA Criteria implementation of Blaze-persistence that translates to JPQL/HQL and offers that feature as extension to the JPA Criteria API.

Look for "Blaze-Persistence JPA-Criteria module dependencies" in the readme: https://github.com/Blazebit/blaze-persistence/blob/master/README.md

Then use BlazeCriteriaBuilder cb = BlazeCriteria.get(criteriaBuilderFactory) and finally blazeCriteriaQuery.getCriteriaBuilder(entityManager) to render the JPA Criteria Query object.



来源:https://stackoverflow.com/questions/17106434/how-to-join-unrelated-entities-with-the-jpa-criteria-api

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!