Repositories¶
Spring Data JPA repositories are interfaces, not classes. Extend JpaRepository and add @EntityGraph overrides to control fetch behavior. The gotcha: entity graphs can't fetch multiple collections ("bags") on list queries.
Pattern¶
@Repository
public interface PlayerRepository extends JpaRepository<Player, Long> {
@Override
@EntityGraph(attributePaths = {"team", "position"}) // Can't fetch multiple "bags" (lists) with EntityGraph
List<Player> findAll();
@Override
@EntityGraph(attributePaths = {"team", "position", "teamsPlayedFor", "receivedAwards", "receivedAwards.award"}) // Can fetch multiple bags when returning only 1 result
Optional<Player> findById(Long id);
}
The bag rule¶
- Single result (
findById): multiple collection paths are fine — one join per bag. - List result (
findAll): multiple bags produce a cartesian explosion, so JPA refuses. Fetch one bag with the graph, the rest lazily or via a separate query.
For named graphs with subgraphs (deeper joins), see Entity graph — note the observation there that joining deep subgraphs on single-row queries can actually slow things down.