from a custom implementation? I want to extend the JpaRepository with a special implementation, so I add th...">

How to reference a "normal" repo? W760> from a custom implementation?

I want to extend the JpaRepository with a special implementation, so I add the MyRepositoryCustom interface and the MyRepositoryImpl class that extends this interface.

Is there a way to call methods from a JpaRepository inside my custom class?

Note. This was also asked as a comment by https://stackoverflow.com/a/377660/213 , but I think this is common enough to merit a separate question.

+6
source share
2 answers

TL; DR

To embed the main repository interface in the user implementation, enter Provider<RepositoryInterface> in the user implementation.

More details

The main task to get this work is to correctly configure dependency injection, since you are going to create a circular dependency between the object you are going to expand and the extension. However, this can be solved as follows:

 interface MyRepository extends Repository<DomainType, Long>, MyRepositoryCustom { // Query methods go here } interface MyRepositoryCustom { // Custom implementation method declarations go here } class MyRepositoryImpl implements MyRepositoryCustom { private final Provider<MyRepository> repository; @Autowired public MyRepositoryImpl(Provider<MyRepository> repository) { this.repository = repository; } // Implement custom methods here } 

The most important part here is the use of Provider<MyRepository> , which will lead to the creation of a w760> lazily initialized proxy for this dependency even when creating an instance for MyRepository in the first place. Inside the implementation of your own methods, you can access the actual bean using the method ….get() .

Provider is an interface from @Inject JSR and thus a standardized interface and requires additional dependency on this JAR API. If you want to stick only to Spring, you can use ObjectFactory as an alternative interface, but get the same behavior.

+7
source

The section entitled Adding custom behavior to all repositories in the documentation should help you.

For example (for illustration only):

 public interface ExtendedJpaRepository<T, ID extends Serializable> extends JpaRepository<T, ID> { T findFirst(); T findLast(); } public class ExtendedJpaRepositoryImpl<T, ID extends Serializable> extends SimpleJpaRepository<T, ID> implements ExtendedJpaRepository<T, ID> { public ExtendedJpaRepositoryImpl(Class<T> domainClass, EntityManager em) { super(domainClass, entityManager); } public T findFirst() { List<T> all = findAll(); return !all.isEmpty() ? all.get(0) : null; } public T findLast() { List<T> all = findAll(); return !all.isEmpty() ? all.get(all.size() - 1) : null; } } 

Then configure ExtendedJpaRepositoryImpl to use according to the instructions given in the documentation above.

Since ExtendedJpaRepositoryImpl extends SimpleJpaRepository (which is an implementation of JpaRepository ), all methods from JpaRepository can be called from ExtendedJpaRepositoryImpl .

+1
source

Source: https://habr.com/ru/post/982084/


All Articles