Uploaded image for project: 'Spring Data JPA'
  1. Spring Data JPA
  2. DATAJPA-749

Context enabled JPA 2.1 @EntityGraph

    Details

    • Type: New Feature
    • Status: Closed
    • Priority: Major
    • Resolution: Won't Fix
    • Affects Version/s: 1.9 M1 (Gosling)
    • Fix Version/s: None
    • Component/s: Core
    • Labels:
      None

      Description

      Currently It's impossible to enable EntityGraph configuration outside of spring data jpa repository. The only possibility is to use @EntityGraph annotation over query method.

      for example

        @EntityGraph("summary")
        Optional<Customer> findByEmailAddress(EmailAddress emailAddress);
      

      Now, it's impossible to reuse this method in different contexts where different entity graph aka fetch profile is required.

      Example I have entity Customer with 2 relations: Invoices and Addresses (OneToMany)

      • In context 1, let's say 'Displaying Customer data with invoices list' I would like to fetch Customer + invoices only.
      • In context 2, let's say 'Displaying Customer data with Addresses' I would like to fetch Customer + addresses only.

      Now, with spring data jpa, I have to create another (second) method and annotate it with another "context" @EntityGraph.
      What is more, my method's name should generate the same JQL Query, but must have different signature (because it's in the same repository), so I will end up with @Query annotation and code duplication.

      The current implementation don't allow to set QueryHints directly on Query - it's possible to annotate method with @QueryHint but it won't solve the problem because it's AFAIK static, and doesn't use SpEL.

      Jpa21Utils with tryGetFetchGraphHints get's the query hints from annotation only, maybe it would be good idea if it could additionally take from other source ? Maybe ThreadLocale or any context object ?
      Maybe, It would be consistent with spring data API if we could provide EntityGraphContext object to have full controll of execution ?

      Proposed solution I "EntityGraphContext"- repository example

        interface SomeRepository ... 
        Optional<Customer> findByEmailAddress(EmailAddress emailAddress, EntityGraphContext graphCtx);
      

      Client code:

      EntityGraphContext graphCtx = EntityGraphContext.enable("summary").withType(EntityGraphType.FETCH);
      Optonal<Customer> customer = someRepository.findByEmailAddress(address, graphCtx);
      

      Proposed solution II "EntityGraphThreadLocalContext"- repository example

        interface SomeRepository ... 
        Optional<Customer> findByEmailAddress(EmailAddress emailAddress);
      

      Client code:

      EntityGraphThreadLocalContext.enable("summary").withType(EntityGraphType.FETCH);
      Optonal<Customer> customer = someRepository.findByEmailAddress(address);
      

        Attachments

          Activity

            People

            • Assignee:
              olivergierke Oliver Drotbohm
              Reporter:
              bmoc Bartłomiej Mocior
              Last updater:
              Jens Schauder
            • Votes:
              13 Vote for this issue
              Watchers:
              17 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved: