Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring Data JPA Fetching

Is there a way to define a Spring Data Specification (returning a JPA predicate) whose sole purpose is to perform eager fetching?

I have an entity which defines various relationships using lazy loading, but there are several queries where I want to return the entire entity representation including all related collections, but the criteria of these queries may vary. I've seen a few posts (e.g. on the spring forum) that discuss the potential introduction of fetch groups, which would likely be the ideal solution; however, since this is not yet part of the JPA spec, Spring Data does not provide support for it.

I'm looking for a reusable way to perform eager fetching on a variety of dynamic queries.

For example, I've considered developing a reusable Specification whose sole purpose is to perform the eager loading, and which could be combined with other specifications, e.g:

private static Specification<MyEntity> eager() {

    return new Specification<MyEntity>() {

        @Override
        public Predicate toPredicate(Root<MyEntity> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
            for (PluralAttribute<? super MyEntity, ?, ?> fetch : root.getModel().getPluralAttributes()) {
                root.fetch(fetch, JoinType.LEFT);
            }
            query.distinct(true);
            return null;
        }

    };
}

The goal of this specification is to reuse it in various queries, e.g:

repository.findAll(where(eager()).and(otherCriteria).or(otherCriteria));

However, the eager fetching specification is not a true predicate, so it returns null, and would cause obvious problems (i.e. NullPointerExceptions) when chained with other predicates.

(Note that this predicate alone does work as expected; i.e. the following query will properly fetch: repository.findAll(eager());).

Is there an appropriate non-null Predicate that can be returned from the "eager" specification, or are there any other reusable approaches for triggering eager fetches using Spring Data JPA specifications (without having to tack the eager load onto another specification)?

like image 731
shelley Avatar asked Mar 18 '13 16:03

shelley


People also ask

What is fetch in JPA?

The FETCH keyword of the JOIN FETCH statement is JPA-specific. It tells the persistence provider to not only join the 2 database tables within the query but to also initialize the association on the returned entity. You can use it with a JOIN and a LEFT JOIN statement.

What is @entity annotation in spring boot?

The @Entity annotation specifies that the class is an entity and is mapped to a database table. The @Table annotation specifies the name of the database table to be used for mapping.

What is difference between JpaRepository and CrudRepository?

CrudRepository provides CRUD functions. PagingAndSortingRepository provides methods to do pagination and sort records. JpaRepository provides JPA related methods such as flushing the persistence context and delete records in a batch.

How does JPA repository connect to database?

If we want to use JPA with MySQL database, we need the mysql-connector-java dependency. We'll also need to define the DataSource configuration. We can do this in a @Configuration class or by using standard Spring Boot properties. Spring Boot will automatically configure a data source based on these properties.


1 Answers

We have improved the handling of null Specifications and Predicates in the course of fixing DATAJPA-300. You might wanna give the 1.4 snapshots a try and see how this affects your scenario.

like image 158
Oliver Drotbohm Avatar answered Oct 30 '22 03:10

Oliver Drotbohm