Search code examples
javahibernatejpajpqlquerydsl

Get single element from JPA nested OneToMany relationship


I have those Entities, It is not from real code, but it's not important I think.

    @Entity
    public class Country{

       private String name;
       //other fields with getters and setters
       @OneToMany
       private List<City> cites;


    }

    @Entity
    public class City {

       private String name;
        //other fields with getters and setters
       @OneToMany
       private List<Employee> emps;//list size could be millions


    }

     @Entity
     public class Employee {

        private String name;
        //other fields with getters and setters

       @OneToMany
       private List<Cars> cars;// list size could be 1000

    }


     @Entity
    public class Car {
      private String name;

      @ManyToOne
      private Employee emp;
    }

I would like to get single Car entity but with other data as well(Country, City, Employee) like this

1 Country in which 1 City in which 1 Empoyee in which 1 Car(which Id I put on select)

So when I do jpa joins from Country like

select c from Country c 
 inner join c.cites ci 
 inner join ci.emps em
  inner join ci.cars car where car.id = ?

I get ALL data in Country(with all cities).

What should I do to get 1 Country,1 City , 1 Employee, 1 Car.

If this is not possible to do with one jpa query then please suggest other way.

All relationships are bidirectional and lazy.

I tried this way. 
1)select car by id. then get Id of employee from car. 
2)select Employee by id - but at this point Employee data are nulls -

I think it is because ManyToOne from Car to Employee is lazy. What do you think ?


Solution

  • Just select the additional entities you want:

    select c, ci, em, car from Country c 
    inner join c.cites ci 
    inner join ci.emps em
    inner join ci.cars car where car.id = ?
    

    Or, since your associations are bidirectional, select the car: it will have a ManyToOne to its employee, which will have a ManyToOne with its city, which will have a ManyToOne with its country:

    select car from Car car where car.id = ?
    

    or simply

    em.find(Car.class, carId);
    

    and now you can do

    car.getEmployee().getCity().getCountry()