What's the difference between "JOIN FETCH" and "JOIN"? - jpa

Supposing I have a Person entity that has #OneToMany relationship with Phone entity. If I want to eagerly fetch Phone entities associated with a Person, I got 2 options:
SELECT p FROM Person p JOIN p.phones
or
SELECT p FROM person p JOIN FETCH p.phones
So what is the difference between them?

Remember that, in the end, JOIN FETCH is always a JOIN.
By default #OneToMany relationships are lazy loaded.
Using JOIN FETCH you load the related entities in advance.
You can find more info reading FETCH JOIN is still a JOIN by Piotr Nowicki

Related

SPring data JPA JPQL multi join entities

I want to join multiple tables by using JPQL query(#Query) with one-to-many mapping in model entities .
Eg: total 8 tables are there to join !! But I am getting error for OneToMany model mapping .
Below Query Works only for #OneToOne mapping
#Query("select new com.infinite.springframework.dto.WPOrderResponse(c.logo ,p.name,c.name ,ks.days)
FROM WPorder w , Project p ,Assignee a ,Customer c ,Domains d ,User u ,wp_kpi wk ,Kpi_Status ks
where w.project=p and p.assignee=a and w.customer=c and w.domains=d and w.wpKpi=wk and wk.kpiStatus=ks and u.id=:userID
group by p.id ,wk.id")
In my opinion, for those complex queries in RDBMS, create a view in the database side firstly.
Then in your project create a read-only(in concept, most of the views in database does not support modifications) Entity for the view for queries, it is more effective.

Left Join an Element collection using JPQL

Suppose I have this classes, notice that entities are not related in anyway.
#Entity
class Laptop {
#Id
String userId;
#Column
String name;
...
}
#Entity
class Foo {
...
#Column
#ElementCollection
List<String> idsPointingToAnEntity;
...
}
Given that I have this Foo class which has an attribute of idsPointingToAnEntity, I could store there a list of Laptop ids or any ids of String. Let's say Foo has idsPointingToAnEntity=[1,2,3], this [1,2,3] has an equivalent Laptop entry in the database.
How can I left join/ join them with ordering in JPQL such given that the result is a list of Foo sorted by Laptop names.
In theory I think it is something like this.
Select f From Foo f LEFT JOIN Laptop l ON l.id IN f.idsPoitingToAnEntity ORDER by l.name
But this is having an error for me since f.idsPoitingToAnEntity is a Join table.
Note: idsPointingToAnEntity can also be another entity making List<Laptop> is not an option
If you are using JPA 2.1 or higher you use JOIN ON in JPQL on unrelated entities. Join the IDs table first, like this:
select f from Foo f
join f.idsPointingToAnEntity id
join Laptop l ON id=l.id
join AnotherEntity a ON id=a.id
You can use no Joins to obtain this result:
SELECT l FROM Laptop l, Foo f
WHERE l.id IN f.idsPointingToAnEntity ORDER BY l.name
Or use CROSS JOIN, a special kind of join that don't require any matching conditions:
SELECT l FROM Laptop l
CROSS JOIN Foo f
WHERE l.id IN f.idsPointingToAnEntity ORDER BY l.name
PS: the problem of using cross join in this scenario, is that it generates the Cartesian Product, not all the rows from left side.
Short answer here is simply don't do that. It is misusing the specific feature and likely to lead to troubles as your list grows. You have no good justification for doing this. If you think the list is small then the database load is minimal and there is no reason to put references into an ElementCollection. If the list gets large you definitely don't want an ElementCollection.
Reference Difference between #OneToMany and #ElementCollection?. An ElementCollection is for creating a OneToMany between, in your case, Foo and idsPointingToAnEntity. It's definitely not meant to be used as a One-To-Many Relationship with Join Table.

JPQL multiple level join fetches

JPQL how to write multiple level join fetches? For example, Order - OrderItem - Product.
select o from Order o left join fetch o.orderItems join fetch o.orderItems.product
Join fetch can not have identification variable. How to write join fetch attribute product of orderItem in the example above?

JPQL inner join and left join

I know what joins are and how to use them in plain SQL but i can't find any explanation of internet to query object with relations. I use entity,getList.size() to query objects that has oneToMany or ManyToMany associations with my entity. I'm wondering is there any way to query object with all his relations.
public Person
#OneToMany
List<Cat>
#ManyToMany
List<DormRoom>
what is do to get all object is;
Person p=PersonDAO.getWithId(1L);
p.getCats.size();
p.getsDormRooms.size();
Now i'm wondering the get fully evulated object with JPQL, CriteriaBuilder and maybe with QueryDSL.
It's called a fetch join:
select distinct p from Person p left join fetch p.cats left join fetch p.dormRooms
where p.id = :id
Beware though:
in Hibernate at least, that will only work if at most 1 of the collections is a bag (i.e. a list without any specified order column).
that will create a query returning the cartesian product of cats * dormRooms. So if a person has 100 cats and 100 dormRooms, 10,000 rows will be retrieved.

JPQL Left Join on clause

I have several entities and want to do a join like this:
SELECT g FROM Gift g
LEFT JOIN Worker w ON g.receiver = w.person
WHERE ....
AND w.company = :companyId
The problem is that there's no direct connection between g.receiver who is a Person and w.person. I don't want to inner join them either, because a receiver of a gift may not be a worker of a company.
I had the same problem, but i didn't find any solution in JPQL, it looks like if you don't have a mapped relation, you can't perform a left join.
I solved the problem with 2 query and a join implemented by code.
Another solution is a native query.