Spring Data JPA Mapping Nested Entities

I’m a little bit confused about using projections in Spring Data JPA. I wanted to optimize my queries by requesting only needed columns (preferably) in one query, and I thought that using projections is a good idea. But it seems that projection with nested projection becomes open and requests all columns and further nesting is impossible.

I’ve tried to find a solution with @Query (cannot find how to map nested lists), @EntityGraph (cannot find how to request only specified column) and @SqlResultSetMapping (cannot find how to make mapping nested lists), but it hasn’t worked for me. Is there any solution except receiving List<Object[]> and manually mapping?

I have the next entities classes (simplified for the question):

public class TestAttempt{
    private Long id;
    private User targetUser;
    private Test test;
}

public class Test{
    private Long id;
    private String name;
    private Set<Question> questions;
}

public class Question{
    private Long id;
    private String name;
    private Test test;
}

And I wanted to write something like this (it can be just TestAttempt with null in unused fields):

public interface TestAttemptList {
    Long getId();
    Test getTest();

    interface Test {
        String getName();

        List<Question> getQuestions();

        interface Question {
            String getName();
        }
    }
}

public interface TestAttemptRepository extends JpaRepository<TestAttempt, Long> {
    List<TestAttemptList> getAllByTargetUserId(Long targetUserId);
}

And in result get something like this:

{
    id: 1,
    test: {
        name: test1,
        questions: [{
            name: quest1
        }, {
            name: quest2
        }]
    }
}

This Post Has One Comment

  1. No Fault

    I’ve done something like this… You’ll have your repository interfaces which will extend CrudRepository et. al. with the full objects (TestAttempt etc) You define your projections separately. The projection interfaces can contain other projection interfaces When the projection interface is used within the given repository the defined methods are applied to the object type the repository is configured for. Something like this.

    public interface TestAttemptSummary {
    Long getId();
    TestSummary getTest();
    }

    public interface TestSummary {
    String getName();
    List getQuestions();
    }

    public interface QuestionSummary {
    String getName();
    }

    public interface TestAttemptRepository extends CrudRepository {
    TestAttemptSummary getTestAttemptSummary();
    }

Leave a Reply