3

Why is it necessary sometimes to cast?

Join<X, Y> a = (Join) Fetch<X, Y> ...

For Example:

Root<Person> personRoot = criteriaQuery.from(Person.class);

@SuppressWarnings("unchecked")
Join<Person, Loan> loanJoin = (Join) personRoot.fetch("loan", JoinType.INNER);
loanJoin.fetch("borrower", JoinType.LEFT);

What is the reason for not doing:

Fetch<Person, Loan> fetchJoin = personRoot.fetch("loan", JoinType.INNER);
fetchJoin.fetch("borrower", JoinType.LEFT);
Neil Stockton
  • 11,383
  • 3
  • 34
  • 29
costajlmpp
  • 71
  • 1
  • 7
  • 1
    Since a `javax.persistence.criteria.Fetch` isn't necessarily a `javax.persistence.criteria.Join`, then it makes no sense (to me). – Neil Stockton May 06 '17 at 06:33

2 Answers2

2

I had to cast Fetch to Join when I wanted to get benefits of both.

e.g., Say you want to get all Employee together with info about their departments and home countries as a single select query with two inner joins. This is possible by adding a root.fetch(...) each for department and homeCountry. If you also wish to order employees based on the population of their respective home countries (please assume you wish to), you will need a Join

Root<Employee> root = query.from(Employee.class);
root.fetch("department");  // <- for an eager join
Join<Employee,Country> joinCountry = (Join) root.fetch("homeCountry");  // <- for an eager join & orderBy
query.select(root).orderBy(builder.asc(joinCountry.get("population")));
Query<Employee> q = sessionFactory.getCurrentSession().createQuery(query);
List<Employee> employees = q.getResultList();

Above code fires a single select * to the db

select
    employee0_.emp_id as emp_id1_0_0_,
    department1_.department_id as depart1_2_1_,
    country2_.country_id as countr1_3_2_,
    employee0_.salary as salary2_0_0_,
    department1_.name as name3_0_0,
    country2_.continent as continent4_0_0
from
    employee employee0_
inner join
    department department1_
        on employee0_.department_id=department1_.department_id 
inner join
    country country2_
        on employee0_.country_id=country2_.country_id 
order by
    country2_.population asc
raghavsood33
  • 749
  • 7
  • 17
  • I think that it doesn't work anymore. I had many troubles with casting Fetch to Join. Do you have some suggestions? – rios0rios0 Jul 05 '21 at 17:41
0

The definite answer is here: How to properly express JPQL "join fetch" with "where" clause as JPA 2 CriteriaQuery?

Basically JPA provides @OneToMany that requires fetching of all related entities to Collection. If you allow aliasing to Fetch (as javax.persistence.criteria.Path.get(String)) it is possible to add where or on expression that limits Collection breaking JPA Java model assumptions.

There are no problem with @*ToOne joins and so some JPA implementations allow casting of Fetch to Join assuming you understand what are you doing ))

Other reading:

gavenkoa
  • 45,285
  • 19
  • 251
  • 303