Reputation: 27
I've always thought what could've been the best way to deal with this problem in Spring/Hibernate. Imagine we have an Entity like House:
public class House {
Long id;
String name;
String address;
List<Person> people;
}
Where Person
is another Entity. Now, if we want to show a list of every house that is stored, we just want some details, id, name and address, we don't want the entire data to be fetched because we are not showing the people in the list.
When we enter a detail view, however, we are interested in showing the people as well.
What's the best way to fetch the people just when you want them, taking care of the LazyInitializationException as well?
Upvotes: 1
Views: 582
Reputation: 18480
You can use the Entity graph in the repository. Just use @EntityGraph to define an ad-hoc entity graph on your method.
@EntityGraph(attributePaths = {"people"})
List<House> findAll();
Here, you can define attributes which you want to fetch as attributePaths
.
Call this when you want to show people otherwise call findAll()
.
And you can use lazy fetching for people
also, whenever you want people
just call the getter of it then JPA will automatically fetch people
in another query.
Upvotes: 1
Reputation: 36223
There are a variety of options. I just highlight the one I use:
JOIN FETCH
If you need the people eager loaded you can create a query like:
select h from House h fetch join people p
If you think this will produce to many queries go for entity graphs.
ENTITY GRAPH
Definition:
@Entity
@NamedEntityGraph(name = "graph.House.people",
attributeNodes = @NamedAttributeNode("people"))
public class House {
Usage with Spring Data JPA:
@EntityGraph(value = "graph.House.people", type = EntityGraphType.LOAD)
List<House> findById(Long id);
But there are more. Please read: https://thoughts-on-java.org/5-ways-to-initialize-lazy-relations-and-when-to-use-them/
Upvotes: 2