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.
The only way to join two unrelated entities with JPA 2.1 and Hibernate versions older than 5.1, is to create a cross join and reduce the cartesian product in the WHERE statement. This is harder to read and does not support outer joins. Hibernate 5.1 introduced explicit joins on unrelated entities.
We can also join multiple entities in a single JPQL query: @Test public void whenMultipleEntitiesAreListedWithJoin_ThenCreatesMultipleJoins() { TypedQuery<Phone> query = entityManager.
The Criteria API is a predefined API used to define queries for entities. It is the alternative way of defining a JPQL query. These queries are type-safe, and portable and easy to modify by changing the syntax. Similar to JPQL it follows abstract schema (easy to edit schema) and embedded objects.
JPQL provides an additional type of identification variable, a join variable, which represent a more limited iteration over specified collections of objects. In JPQL, JOIN can only appear in a FROM clause. The INNER keyword is optional (i.e. INNER JOIN is equivalent to JOIN).
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));
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With