Skip to content

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.

See also