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

Custom implementation of CrudRepository.save(…) not called if generics not declared exactly

    XMLWordPrintable

    Details

    • Sprint:
      Kay M2

      Description

      This issue is in conjunction with this spring-data-dynamodb issue.

      I've spent a few hours on this bug and have tracked down the root cause as well as a workaround, but there appears to be no solution.

      Library Versions

      • spring-data-dynamoDB version: 4.5.0
      • Spring-data-commons version: 1.13.1-RELEASE

      Situation

      I have a base repository interface:

      interface FooRepository extends CrudRepository<Foo, Long>, FooRepositoryCustom{}
      

      ...and a custom repository interface:

      interface UserRepositoryCustom {
          Foo doNonstandardThing(Foo foo);
      }
      

      ... and a custom repository implementation:

      class UserRepositoryImpl implements UserRepositoryCustom {
          public Foo save(Foo foo) { … }
          public Foo doNonstandardThing(Foo foo) { … }
      }
      

      ... If I use this custom repository:

      @Service
      public class FooService {
      
          private final FooRepository fooRepo;
          
          @Autowired
          public FooService(FooRepository fooRepo) {
              this.fooRepo = fooRepo;
          }
      
          public Bar processFoo(Foo foo) {
              fooRepo.save(foo);
          }
      }
      

      With spring-data-dynamodb:4.2.3 using spring-data-commons:1.11.4-RELEASE, the fooRepo.save(…) call in FooService would call the save(…) method on FooRepositoryCustom. with spring-data-dynamodb:4.5.0 and spring-data-commons:1.13.1-RELEASE, it actually calls SimpleDynamoDBCrudRepository.save(…), which is the base implementation used by the Spring scoped proxy.

      After some quality time in side-by-side debuggers with my code running on the new and old versions of the library, I've tracked the offending code change down to this commit as well as a few other changes within `DefaultRepositoryInformation` and specifically, the parametersMatch(…) method. The logic over whether a custom repository method "matches" seems to have changed in a very odd and restrictive way.

      What I can't figure out is why exactly Spring cannot tell that a method with the exact needed signature in my custom repository is not suitable to call vs. the proxy method in the spring-data-dynamodb library.

      Workaround

      Changing the Custom Repository interface like so:

      interface FooRepository extends CrudRepository<Foo, Long>, FooRepositoryCustom{
      
          @Override
          <X extends Foo> X save(X foo);
      }
      

      causes the correct method to be invoked, but this should not be necessary; it is also tedious to do for every repository that happens to have a custom implementation of a "standard" CrudRepository method.

      Desired State

      Methods in custom repositories should be respected by return and parameter value.

        Attachments

          Issue Links

            Activity

              People

              Assignee:
              olivergierke Oliver Drotbohm
              Reporter:
              RyonDay Ryon Day
              Last updater:
              Mark Paluch
              Votes:
              0 Vote for this issue
              Watchers:
              2 Start watching this issue

                Dates

                Created:
                Updated:
                Resolved: