Let's say I have 3 models as follows:
@Entity
@Data
class Continent {
@Id
private Long id;
private String name;
...
}
@Entity
@Data
class Country {
@Id
private Long id;
@ManyToOne(fetch = FetchType.LAZY)
private Continent continent;
private String name;
...
}
@Entity
@Data
class City {
@Id
private Long id;
@ManyToOne(fetch = FetchType.LAZY)
private Country country;
private String name;
...
}
I want to fetch Continent by it's Primary key id
. But I also want all the Countries that belong to a Continent and all the cities that belong to a Country.
Currently I am making 3 separate calls, first query Continent table, then query Country table by FK Continent id and at last querying City table by FK Country id.
I want to query everything in a single call. So I add bidirectional OneToMany relationship with EAGER fetching as follows:
@Entity
@Data
class Continent {
@Id
private Long id;
private String name;
...
@OneToMany(mappedBy = "continent", fetch = FetchType.EAGER)
private List<Country> countries;
}
@Entity
@Data
class Country {
@Id
private Long id;
@ManyToOne(fetch = FetchType.LAZY)
private Continent continent;
private String name;
...
@OneToMany(mappedBy = "country", fetch = FetchType.EAGER)
private List<City> cities;
}
@Entity
@Data
class City {
@Id
private Long id;
@ManyToOne(fetch = FetchType.LAZY)
private Country country;
private String name;
...
}
Everything works fine. I see two left outer joins in Hibernate generated query.
Now the issue is I do not want to eagerly fetch all the related associations everytime. One option is to change all OneToMany associations to LAZY and have join fetch
in JPQL query.
So for fetching all the Countries of a Continent, I can have a JPQL query as below
SELECT u FROM Continent u JOIN FETCH u.countries WHERE u.id=?1
But for a hierarchy like Continent -> Country -> City, where I also want to populate the City fields, I am unable to design a JPQL query. Any ideas how I proceed further?
Edit: Future readers might be interested in reading JPA : How to define @NamedEntityGraph for 3 levels?