I want to extend a JpaRepository
with a custom implementation, so i add a MyRepositoryCustom
interface and a MyRepositoryImpl
class extending this interface.
Is there a way to call methods from JpaRepository
inside my custom class?
Note: This was also asked as a comment on https://stackoverflow.com/a/11881203/40064, but I think it is common enough to deserve a separate question.
tl;dr
To inject the core repository interface into a custom implementation, inject a
Provider<RepositoryInterface>
into the custom implementation.Details
The core challenge to get that working is setting up the dependency injection correctly as you are about to create a cyclic dependency between the object you're about to extend and the extension. However this can be solved as follows:
The most important part here is using
Provider<MyRepository>
which will cause Spring to create a lazily-initialized proxy for that dependency even while it's creating an instance forMyRepository
in the first place. Inside the implementation of your custom methods you can then access the actual bean using the….get()
-method.Provider
is an interface from the@Inject
JSR and thus a standardized interface and requires an additional dependency to that API JAR. If you want to stick to Spring only, you can usedObjectFactory
as an alternative interface but get the very same behavior.The section titled Adding custom behaviour to all repositories in the documentation should help you.
For example (only for illustration purposes):
Then, configure
ExtendedJpaRepositoryImpl
for use as per the instructions given in the documentation linked above.Since
ExtendedJpaRepositoryImpl
extendsSimpleJpaRepository
(which is an implementation ofJpaRepository
), all methods fromJpaRepository
can be called fromExtendedJpaRepositoryImpl
.