Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to left join two unrelated entities with JPA criteria api?

using JPA 2.1 and hibernate 5.1.x, this is possible with JPQL

select s.lowerBound,
l.status
...
from Serie s
left join Line l on
s.lowerBound between l.lineStart and l.lineEnd

how do i write this using Criteria api? i attempted this

Root<Serie> serieRoot = query.from(Serie.class);
Root<Line> lineRoot query.from(Line.class);
query.where(criteriaBuilder.between(s.get("lowerBound"), l.get("lineStart"), s.get("lineEnd")))

but this doesn't allow me to specify it's a left join.

like image 771
kfc Avatar asked Jan 24 '17 20:01

kfc


People also ask

How do I join unrelated entities with JPA?

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.

How does JPA handle joins?

First of all, JPA only creates an implicit inner join when we specify a path expression. For example, when we want to select only the Employees that have a Department, and we don't use a path expression like e. department, we should use the JOIN keyword in our query.

What is JPA Criteria API?

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.


1 Answers

What you do with your Criteria query doesn't allow you to specify that as a left join, because it's not really a left join. You just have multiple roots in your query, and according to the Hibernate documentation that uses cartesian products, however with a left join you get nulls on the right side if there are no matches.

Since the Form interface only allows you to create joins from attributes of your entity, I think what you want to achieve is not doable with the Criteria API. You either have to do two queries to the database or you have to use JPQL or SQL to do it in one query.

like image 163
ytg Avatar answered Sep 30 '22 00:09

ytg