-
In addition to
spring-data-jpa
, add the library dependency :<dependency> <groupId>com.cosium.spring.data</groupId> <artifactId>spring-data-jpa-entity-graph</artifactId> <version>${spring-data-jpa-entity-graph.version}</version> </dependency>
-
In your Spring configuration, set the repository factory bean class to
EntityGraphJpaRepositoryFactoryBean
:@Configuration @EnableJpaRepositories(repositoryFactoryBeanClass = EntityGraphJpaRepositoryFactoryBean.class) public class DataRepositoryConfiguration { //... }
-
Make sure your repositories extend the Spring Data standard ones or the library provided repositories:
EntityGraphJpaRepository
which is equivalent to standardJpaRepository
EntityGraphJpaSpecificationExecutor
which is equivalent to standardJpaSpecificationExecutor
EntityGraphQuerydslPredicateExecutor
which is equivalent to standardQuerydslPredicateExecutor
EntityGraphCrudRepository
which is equivalent to standardCrudRepository
EntityGraphPagingAndSortingRepository
which is equivalent to standardPagingAndSortingRepository
EntityGraphQueryByExampleExecutor
which is equivalent to standardQueryByExampleExecutor
Let's consider the following entities and repository :
@Entity
public class Brand {
@Id
private long id = 0;
private String name;
//...
}
@NamedEntityGraphs(value = {
@NamedEntityGraph(name = "Product.brand", attributeNodes = {
@NamedAttributeNode("brand")
})
})
@Entity
public class Product {
@Id
private long id = 0;
private String name;
@ManyToOne(fetch = FetchType.LAZY)
private Brand brand;
//...
}
public interface ProductRepository extends EntityGraphJpaRepository<Product, Long> {
List<Product> findByName(String name, EntityGraph entityGraph);
}
You can pass the entity graph to the findByName
method :
// This will apply 'Product.brand' named EntityGraph to findByName
productRepository.findByName("MyProduct", EntityGraphs.named("Product.brand"));
Or to the findOne
method :
// This will apply 'Product.brand' named EntityGraph to findOne
productRepository.findById(1L, EntityGraphs.named("Product.brand"));
Or any method you like.
You can also pass a dynamically built EntityGraph by using DynamicEntityGraph
, it's also accessible through a helper method:
productRepository.findById(1L, EntityGraphUtils.fromAttributePaths("brand", "maker"));
This is similar to Spring's ad-hoc attribute paths, and equivalent to writing this in your repository's interface:
@EntityGraph(attributePaths = { "brand", "maker" })
Product findById(Long id);
For an Entity, you can define its default EntityGraph.
An Entity default EntityGraph will be used each time the Entity repository method is called without EntityGraph.
A default EntityGraph name must end with .default
.
@NamedEntityGraphs(value = {
@NamedEntityGraph(name = "Product.default", attributeNodes = {
@NamedAttributeNode("brand")
})
})
@Entity
public class Product {
@Id
private long id = 0;
private String name;
@ManyToOne(fetch = FetchType.LAZY)
private Brand brand;
//...
}
// This call will make use of "Product.default" EntityGraph.
productRepository.findById(1L);