Uploaded image for project: 'Spring Data Commons'
  1. Spring Data Commons
  2. DATACMNS-89

Support for projections in repository query methods

    Details

    • Type: New Feature
    • Status: Closed
    • Priority: Minor
    • Resolution: Fixed
    • Affects Version/s: None
    • Fix Version/s: 1.12 M1 (Hopper)
    • Component/s: None
    • Labels:
      None
    • Sprint:
      57 - Fowler Aftermath, 58 - Gosling M1, 59 - Evans / Fowler SR, Gosling RC1, Hopper M1

      Description

      The findBy clause of the derived queries currently allows setting a distinct flag already. We could add property projections as well:

      interface PersonRepository extends Repository<Person, Long> {
       
        List<Map<String, String>> findNameAndAgeByGroupTitle(String title);
      }

      The return types should act as follows:

      • Map<String, ${type or Object}> expecting a single returned result consisting of multiple key-value pairs.
      • ${type} - expecting a single result. We'll trigger a DTO projection, e.g. select new ${type}(name, age) ...
      • Iterable of both possibilities triggering the very same expecting multiple results
      • Page of both triggering pagination.

        Issue Links

          Activity

          Hide
          stanaccy Nick Pratt added a comment -

          We find a common operation is to load all values of a specific type without wanting to trigger a full object load. Something like List<String> findAllNames(); where 'name' is a property of the class. Supporting Set<String> findAllNames() to automatically provide a unique selection would be helpful.

          Show
          stanaccy Nick Pratt added a comment - We find a common operation is to load all values of a specific type without wanting to trigger a full object load. Something like List<String> findAllNames(); where 'name' is a property of the class. Supporting Set<String> findAllNames() to automatically provide a unique selection would be helpful.
          Hide
          alan-czajkowski Alan Czajkowski added a comment - - edited

          agreed, i would really like to load a list of one (or more attributes), examples:

          List<Long> findId()

          List<Map<String, Object>> findIdAndName()

          Show
          alan-czajkowski Alan Czajkowski added a comment - - edited agreed, i would really like to load a list of one (or more attributes), examples: List<Long> findId() List<Map<String, Object>> findIdAndName()
          Hide
          olivergierke Oliver Gierke added a comment - - edited

          The prototype available in the feature branch for this ticket has infrastructure for the following functionality:

          1. The return type is a class - We inspect the type for persistent properties and use the store’s projection capabilities to limit the data queried to the set of properties. We use the standard entity instantiation mechanism to materialize object instances of that class.
          2. The return type is an interface without a method annotated with @Value - We can create a Map-backed proxy for the query result which can have been restricted to the properties defined in the projection type.
          3. The return type is an interface with a method annotated with @Value - We unfortunately cannot optimize anything here as the SpEL expressions used in @Value might refer to the target domain object in its entirety. To create the projection we’d leverage the projection subsystem already available in Spring Data REST.
          4. If the query method is generic and takes a binding Class parameter (i.e. <T> Collection<T> findBy…(…, Class<T> type) we dynamically determine the type to project to on every query execution and apply the semantics defined above.

          It became pretty obvious that putting the fields to retrieve in the method name becomes pretty awkward and would probably break a few existing users as the find… clause hasn't been restricted so far. We generally recommend to use dedicated projection interfaces or DTOs to define what is supposed to be read.

          See the examples already available here. Feedback welcome!

          Show
          olivergierke Oliver Gierke added a comment - - edited The prototype available in the feature branch for this ticket has infrastructure for the following functionality: 1. The return type is a class - We inspect the type for persistent properties and use the store’s projection capabilities to limit the data queried to the set of properties. We use the standard entity instantiation mechanism to materialize object instances of that class. 2. The return type is an interface without a method annotated with @Value - We can create a Map-backed proxy for the query result which can have been restricted to the properties defined in the projection type. 3. The return type is an interface with a method annotated with @Value - We unfortunately cannot optimize anything here as the SpEL expressions used in @Value might refer to the target domain object in its entirety. To create the projection we’d leverage the projection subsystem already available in Spring Data REST. 4. If the query method is generic and takes a binding Class parameter (i.e. <T> Collection<T> findBy…(…, Class<T> type) we dynamically determine the type to project to on every query execution and apply the semantics defined above. It became pretty obvious that putting the fields to retrieve in the method name becomes pretty awkward and would probably break a few existing users as the find… clause hasn't been restricted so far. We generally recommend to use dedicated projection interfaces or DTOs to define what is supposed to be read. See the examples already available here . Feedback welcome!
          Hide
          alan-czajkowski Alan Czajkowski added a comment -

          looking good! thanks for the update, keep up the good work

          Show
          alan-czajkowski Alan Czajkowski added a comment - looking good! thanks for the update, keep up the good work

            People

            • Assignee:
              olivergierke Oliver Gierke
              Reporter:
              mhunger Michael Hunger
              Last updater:
              Oliver Gierke
            • Votes:
              19 Vote for this issue
              Watchers:
              17 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved:

                Agile